76 "Filesize does not match expected format",
77 "File version number not <4, as expected",
78 "Unable to allocate memory to store data",
79 "Unable to detect endian-ness in file" 83 "Unable to determine filesize",
84 "Filesize indicates that file contains a non-integer number of entries",
85 "Unable to open file",
86 "Unable to allocate memory for reading file contents",
87 "Unable to perform read operation on file",
88 "Read past end of file requested",
89 "Entry in file appears to be invalid",
93 unsigned int fixedRecordReader(
const char *filename,
bool (*recordReader)(
const char *bufRead,
const char *destBuf),
94 size_t recordSize, std::vector<T> &outputData)
102 if(fileSize % recordSize )
105 std::ifstream f(filename);
111 size_t numFileEntries = fileSize/recordSize;
115 buffer =
new char[recordSize];
116 outputData.resize(numFileEntries);
118 catch(std::bad_alloc)
123 for(
size_t ui=0;ui<numFileEntries;ui++)
126 if(!f.read(buffer,recordSize))
132 if(!(*recordReader)(buffer,(
char *)(&outputData[ui])))
144 unsigned int fixedRecordChunkReader(
const char *filename,
bool (*recordReader)(
const char *bufRead,
const char *destBuf),
145 size_t recordSize, std::vector<T> &outputData,
146 unsigned int chunkSize,
unsigned int chunkOffset,
unsigned int &nEntriesLeft)
158 if(fileSize % recordSize )
162 std::ifstream f(filename);
167 size_t numFileEntries = fileSize/recordSize;
168 unsigned int entryOffset=chunkOffset*chunkSize;
171 if(entryOffset > numFileEntries)
176 size_t nEntriesToRead = std::min(numFileEntries-entryOffset,(
size_t)chunkSize);
187 buffer =
new char[recordSize];
188 outputData.resize(nEntriesToRead);
190 catch(std::bad_alloc)
196 f.seekg(entryOffset*recordSize);
198 for(
size_t ui=0; ui<nEntriesToRead; ui++)
201 if(!f.read(buffer,recordSize))
207 if(!(*recordReader)(buffer,(
char *)(&outputData[ui])))
214 nEntriesLeft=numFileEntries-(chunkOffset*chunkSize+nEntriesToRead);
240 const char *posErrStrings[] = {
"",
241 "Memory allocation failure on POS load",
242 "Error opening file for load",
243 "Pos file size appears to have non-integer number of entries",
245 "Error reading from pos file (after open)",
246 "Error - Found NaN in pos file",
252 return posErrStrings[errCode];
256 unsigned int loadPosFile(vector<IonHit> &posIons,
const char *posFile)
261 const unsigned int BUFFERSIZE=8192;
262 char *buffer=
new char[BUFFERSIZE];
268 std::ifstream CFile(posFile,std::ios::binary);
276 CFile.seekg(0,std::ios::end);
277 std::ifstream::pos_type fileSize=CFile.tellg();
278 CFile.seekg(0,std::ios::beg);
288 unsigned int pointCount=0;
290 std::ifstream::pos_type curBufferSize=BUFFERSIZE;
292 if(fileSize %
sizeof(
IONHIT))
298 while(fileSize < curBufferSize)
299 curBufferSize = curBufferSize >> 1;
303 posIons.resize(fileSize/(
sizeof(
IONHIT)));
305 catch(std::bad_alloc)
314 while(CFile.tellg() <= fileSize-curBufferSize)
317 CFile.read(buffer,curBufferSize);
325 hitStruct = (
IONHIT *)buffer;
329 for(ui=0; ui<curBufferSize; ui+=(
sizeof(
IONHIT)))
335 #ifdef __LITTLE_ENDIAN__ 345 posIons[pointCount] = hit;
353 curBufferSize = curBufferSize >> 1 ;
354 }
while(curBufferSize >=
sizeof(
IONHIT));
356 ASSERT((
unsigned int)CFile.tellg() == fileSize);
358 ASSERT(pointCount == posIons.size());
364 unsigned int loadPosFile(vector<IonHit> &posIons,
const char *posFile,
unsigned int limitCount)
369 std::ifstream CFile(posFile,std::ios::binary);
374 CFile.seekg(0,std::ios::end);
375 auto fileSize=CFile.tellg();
380 CFile.seekg(0,std::ios::beg);
382 const unsigned int IONHIT_SIZE=16;
383 if(fileSize % IONHIT_SIZE)
386 auto maxIons =fileSize/IONHIT_SIZE;
387 limitCount=std::min(limitCount,(
unsigned int)maxIons);
390 if(limitCount == maxIons)
399 std::vector<size_t> ionsToLoad;
406 posIons.resize(limitCount);
411 catch(std::bad_alloc)
420 std::sort(ionsToLoad.begin(),ionsToLoad.end());
426 std::ios::pos_type nextIonPos;
428 char buffer[IONHIT_SIZE];
429 for(
size_t ui=0;ui<ionsToLoad.size(); ui++)
431 nextIonPos = ionsToLoad[ui]*IONHIT_SIZE;
433 if(CFile.tellg() !=nextIonPos )
434 CFile.seekg(nextIonPos);
437 CFile.read(buffer,IONHIT_SIZE);
443 hitStruct = (
IONHIT*)buffer;
449 #ifdef __LITTLE_ENDIAN__ 450 posIons[ui].switchEndian();
453 if(posIons[ui].hasNaN())
463 unsigned int savePosFile(
const vector<IonHit> &ionVec,
const char *filename,
bool append)
465 auto flags = std::ios::binary;
467 flags|=std::ios::app;
469 std::ofstream CFile(filename,flags);
470 float floatBuffer[4];
476 CFile.seekp(std::ios::end);
479 for(
unsigned int ui=0; ui<ionVec.size(); ui++)
482 for(
unsigned int uj=0;uj<4;uj++)
484 floatBuffer[uj]=ionVec[ui][uj];
485 #ifdef __LITTLE_ENDIAN__ 489 CFile.write((
char *)floatBuffer,4*
sizeof(
float));
499 unsigned int savePosFile(
const vector<Point3D> &ptVec,
float mass,
const char *filename,
bool append)
501 auto flags = std::ios::binary;
503 flags|=std::ios::app;
505 std::ofstream CFile(filename,flags);
506 float floatBuffer[4];
512 CFile.seekp(std::ios::end);
514 #ifdef __LITTLE_ENDIAN__ 518 for(
unsigned int ui=0; ui<ptVec.size(); ui++)
521 for(
unsigned int uj=0;uj<3;uj++)
523 floatBuffer[uj]=ptVec[ui][uj];
524 #ifdef __LITTLE_ENDIAN__ 528 CFile.write((
char *)floatBuffer,3*
sizeof(
float));
529 CFile.write((
char *)&mass,1*
sizeof(
float));
540 ifstream f(posfile,std::ios::binary);
545 f.seekg(0,std::ios::end);
547 fileSize = f.tellg();
548 f.seekg(0,std::ios::beg);
559 const unsigned int HEADER_ENTRIES=4;
560 if(s.size() != HEADER_ENTRIES)
571 else if(s[0] ==
"ASCII")
580 unsigned int MAX_RECORD_SIZE=18;
581 char *buffer=
new char[MAX_RECORD_SIZE];
596 if(s[2] ==
"1" || s[2] ==
"0" )
605 size_t numbersPresent;
608 else if (s[3] ==
"0")
609 numbersPresent=
false;
618 size_t recordSize=( (numbersPresent ? 1:0 )*
sizeof(
unsigned int) +
619 3*
sizeof(float) + (idsPresent ?1:0)*
sizeof(short));
622 if(fileSize -f.tellg() !=recordSize*numEntries)
629 posIons.resize(numEntries);
630 for(
size_t ui=0;ui<numEntries; ui++)
632 f.read(buffer,recordSize);
635 #ifdef __LITTLE_ENDIAN__ 638 static_assert(
false,
"Big endian");
646 #pragma omp parallel for 647 for(
size_t ui=0;ui<numEntries;ui++)
650 posIons[ui].setPos(posIons[ui].getPos()*1e9);
669 std::string data,tmp;
672 data+=tmp +
" 0 0\n";
674 f.write(data.c_str(),data.size());
677 ASSERT(
sizeof(
short) == 2);
678 for(
size_t ui=0;ui<posIons.size();ui++)
683 posIons[ui].getPos().copyValueArr(floats);
686 for(
size_t uj=0;uj<3;uj++)
688 #ifdef __BIG_ENDIAN__ 694 id=posIons[ui].getMassToCharge();
695 f.write((
const char *)floats,
sizeof(
float)*3);
696 f.write((
const char *)&
id,
sizeof(
short));
703 unsigned int saveTapsimBin(
const vector<IonHit> &posIons,
const char *filename)
705 ofstream f(filename,std::ios::binary);
713 static_assert(
sizeof(
float) == 4,
"size of float not 4");
716 float *srcPtr = (
float*)src;
719 for(
size_t ui=0;ui<9;ui++)
723 if( std::isnan(srcPtr[ui]) || std::isinf(srcPtr[ui]))
756 size_t loadEposFile(std::vector<EPOS_ENTRY> &outData,
const char *filename)
766 unsigned int nChunksToRead,
unsigned int chunkOffset,
unsigned int &nChunksLeft)
772 outData,nChunksToRead,chunkOffset,nChunksLeft);
779 "\"C\" line (exp. parameters) not in expected format",
780 "\"I\" line (Detector parameters) not in expected format",
781 "\"-\" line (Time-of-flights) not in expected format",
782 "\"V\" line (voltage data) not in expected format",
783 "Error interpreting \"V\" line (voltage data) data",
784 "Missing beta value from \"V\" line - needs to be in voltage, or in system header (\"C\" line",
785 "Incorrect number of \"V\" line (voltage data) data entries",
786 "Unknown linetype in data file",
787 "\"P\" line (detector channels) not in expected format",
788 "Unable to interpret channels line",
789 "Incorrect number of events in \"S\" (hit position) line",
790 "Unable to interpret event data on \"S\" (hit position) line",
791 "Unable to parse \"S\" (hit position) line event count (eg 8 in S8 ...)",
792 "\"S\" (hit position) line data not preceded by TOF data, as it should have been",
793 "Duplicate system data/experiment setup (\"C\") entry found -- there can only be one",
794 "Duplicate detector (\"I\") data entry found -- there can only be one",
795 "Trailing \"-\" line found -- should have be followed by a \"S\" line, but wasn't.",
796 "Duplicate\"-\" line found -- should have be followed by a \"S\" line, but wasn't.",
797 "Unable to open file",
798 "unable to read file, after opening",
807 unsigned int &badLine,
unsigned int &
progress,
808 std::atomic<bool> &wantAbort,
unsigned int nDelayLines,
bool strictMode)
813 const char COMMENT_MARKER=
'*';
817 size_t totalFilesize;
821 std::ifstream f(file);
830 OPS_LINE_OTHER_OR_NONE
833 bool haveSystemParams=
false;
834 bool haveDetectorSize=
false;
836 unsigned int lastLine=OPS_LINE_OTHER_OR_NONE;
838 vector<string> strVec;
860 if(!strLine.size() || strLine[0] == COMMENT_MARKER)
879 haveSystemParams =
true;
883 if(strVec.size() != 5)
898 lastLine=OPS_LINE_OTHER_OR_NONE;
907 haveDetectorSize=
true;
913 if(strVec.size() != 2)
918 lastLine=OPS_LINE_OTHER_OR_NONE;
927 if(lastLine !=OPS_LINE_DASH)
946 if((strVec.size()-1) /(nDelayLines+1)< data.
eventData.back().size())
951 lastLine=OPS_LINE_OTHER_OR_NONE;
960 strVec[0]= strVec[0].substr(1);
962 unsigned int numEvents;
970 lastLine=OPS_LINE_OTHER_OR_NONE;
976 if(numEvents != (strVec.size()-1)/(nDelayLines+1))
980 vector<SINGLE_HIT> &curHits=data.
eventData.back();
985 if(curHits.size()> numEvents)
992 lastLine=OPS_LINE_OTHER_OR_NONE;
1000 curHits.resize(numEvents,h);
1008 tofs.resize(curHits.size());
1009 for(
unsigned int ui=0;ui<curHits.size();ui++)
1010 tofs[ui]=curHits[ui].tof;
1014 bool everythingOK=
true;
1015 unsigned int timingIndex=curHits.size()*2+1;
1016 for(
unsigned int ui=1;ui<timingIndex;ui+=2)
1019 unsigned int offset;
1049 lastLine=OPS_LINE_OTHER_OR_NONE;
1053 vector<unsigned int> timeMap;
1055 for(
unsigned int ui=timingIndex; ui<strVec.size();ui++)
1057 unsigned int mapEntry;
1070 timeMap.push_back(mapEntry);
1076 lastLine=OPS_LINE_OTHER_OR_NONE;
1079 ASSERT(timeMap.size() == curHits.size());
1083 for(
unsigned int ui=0;ui<curHits.size();ui++)
1086 curHits[ui].tof=tofs[timeMap[ui]-1];
1091 lastLine=OPS_LINE_OTHER_OR_NONE;
1097 if(lastLine==OPS_LINE_DASH)
1100 if(strVec.size() < 2)
1119 for(
unsigned int ui=1; ui< strVec.size(); ui++)
1125 tofs.push_back(timeOfFlight);
1128 vector<SINGLE_HIT> s;
1130 s.resize(tofs.size());
1131 for(
unsigned int ui=0;ui<tofs.size();ui++)
1132 s[ui].tof =tofs[ui];
1135 lastLine=OPS_LINE_DASH;
1143 if(! (strVec.size() == 4 || strVec.size() == 3) )
1155 if(strVec.size() ==4)
1163 if(!haveSystemParams)
1170 lastLine=OPS_LINE_OTHER_OR_NONE;
1175 if(strVec.size() != 2)
1193 progress=(float)f.tellg()/(float)totalFilesize*100.0f;
1196 if(lastLine==OPS_LINE_DASH)
1212 unsigned int loadATOFile(
const char *fileName, vector<ATO_ENTRY> &ions,
unsigned int forceEndian)
1215 std::ifstream CFile(fileName,std::ios::binary);
1221 CFile.seekg(0,std::ios::end);
1222 size_t fileSize=CFile.tellg();
1250 const size_t ATO_HEADER_SIZE=8;
1251 const size_t ATO_RECORD_SIZE = 14*4;
1252 const size_t ATO_MIN_FILESIZE = 8 + ATO_RECORD_SIZE;
1254 if(fileSize < ATO_MIN_FILESIZE)
1260 size_t pointCount=0;
1261 if((fileSize - ATO_HEADER_SIZE) % (ATO_RECORD_SIZE))
1267 unsigned int versionByte;
1268 CFile.read((
char*)&versionByte,
sizeof(
unsigned int));
1276 if(!versionByte || versionByte > 5)
1280 pointCount = (fileSize-ATO_HEADER_SIZE)/ATO_RECORD_SIZE;
1284 ions.resize(pointCount);
1286 catch(std::bad_alloc)
1303 #ifdef __LITTLE_ENDIAN__ 1304 endianFlip=(forceEndian == 2);
1305 #elif defined(__BIG_ENDIAN__) 1306 endianFlip=(forceEndian == 1);
1312 size_t numToCheck=std::min(pointCount,(
size_t)100);
1315 vector<unsigned int> randomNumbers;
1321 std::sort(randomNumbers.begin(),randomNumbers.end());
1324 bool badFloat[2]={
false,
false };
1326 bool veryLargeNumber[2] = {
false,
false };
1329 auto buffer =
new float[ATO_RECORD_SIZE/4];
1330 for(
size_t ui=0;ui<numToCheck;ui++)
1333 offset=randomNumbers[ui];
1335 CFile.seekg(ATO_HEADER_SIZE + ATO_RECORD_SIZE*offset);
1336 CFile.read((
char*)buffer,ATO_RECORD_SIZE);
1338 const unsigned int BYTES_TO_CHECK[] = { 0,1,2,3,5,6,8,9,10 };
1339 const size_t CHECKBYTES = 9;
1342 for(
size_t uj=0;uj<CHECKBYTES;uj++)
1344 if(std::isnan(buffer[BYTES_TO_CHECK[uj]]) ||
1345 std::isinf(buffer[BYTES_TO_CHECK[uj]]))
1351 if(std::isnan(buffer[BYTES_TO_CHECK[uj]]) ||
1352 std::isinf(buffer[BYTES_TO_CHECK[uj]]))
1364 if( buffer[3] < -1000.0f)
1365 veryLargeNumber[0] =
true;
1368 if( fabs(buffer[6]) > 1000.0f || fabs(buffer[10]) > 1000.0f)
1369 veryLargeNumber[0] =
true;
1375 if( buffer[3] < -1000.0f)
1376 veryLargeNumber[1] =
true;
1378 if( fabs(buffer[6]) > 1000.0f || fabs(buffer[10]) > 1000.0f)
1379 veryLargeNumber[1] =
true;
1390 if(badFloat[0] != badFloat[1])
1392 endianFlip=(badFloat[0]);
1394 else if(veryLargeNumber[0] != veryLargeNumber[1])
1396 endianFlip=veryLargeNumber[0];
1401 #ifdef __LITTLE_ENDIAN__ 1428 auto buffer =
new float[ATO_RECORD_SIZE/4];
1434 while((
size_t)CFile.tellg() < fileSize)
1436 CFile.read((
char*)buffer,ATO_RECORD_SIZE);
1438 for(
size_t ui=0;ui<ATO_RECORD_SIZE;ui++)
1441 float *fBuf=(
float*)buffer;
1442 ions[curPos].x = fBuf[0];
1443 ions[curPos].y = fBuf[1];
1444 ions[curPos].z = fBuf[2];
1445 ions[curPos].mass= fBuf[3];
1446 ions[curPos].approxPulse= fBuf[5];
1447 ions[curPos].voltage = fBuf[6];
1448 ions[curPos].tof= fBuf[7];
1449 ions[curPos].detectorX = fBuf[8];
1450 ions[curPos].detectorY = fBuf[9];
1451 ions[curPos].pulseVoltage= fBuf[10];
1459 while((
size_t)CFile.tellg() < fileSize)
1461 CFile.read((
char*)buffer,ATO_RECORD_SIZE);
1463 float *fBuf=(
float*)buffer;
1464 ions[curPos].x = fBuf[0];
1465 ions[curPos].y = fBuf[1];
1466 ions[curPos].z = fBuf[2];
1467 ions[curPos].mass= fBuf[3];
1468 ions[curPos].approxPulse= fBuf[5];
1469 ions[curPos].voltage = fBuf[6];
1470 ions[curPos].tof= fBuf[7];
1471 ions[curPos].detectorX = fBuf[8];
1472 ions[curPos].detectorY = fBuf[9];
1473 ions[curPos].pulseVoltage= fBuf[10];
1485 bool strhas(
const char *cpTest,
const char *cpPossible)
1493 if(*search == *cpTest)
1504 unsigned int loadTextData(
const char *cpFilename, vector<vector<float> > &dataVec,vector<string> &headerVec,
1505 const char *delim,
bool allowNan,
bool allowConvFails,
unsigned int headerCount)
1507 const unsigned int BUFFER_SIZE=8192;
1508 char inBuffer[BUFFER_SIZE];
1510 unsigned int num_fields=0;
1513 #if !defined(WIN32) && !defined(_WIN64) 1520 std::ifstream CFile(cpFilename);
1527 vector<string> strVec;
1530 vector<string> prevStrs;
1531 while(CFile.good() && !CFile.eof() && atHeader)
1534 if(!CFile.getline(inBuffer,BUFFER_SIZE))
1550 num_fields = strVec.size();
1551 dataVec.resize(num_fields);
1556 if(headerCount !=-1)
1569 if(num_fields >= 1 && strVec[0].size())
1575 vector<float> values;
1577 for(
unsigned int ui=0; ui<num_fields; ui++)
1582 if(strVec[ui].find_first_not_of(
"0123456789.Ee+-Na")
1592 if(!allowNan || strVec[ui] !=
"NaN")
1599 values.push_back(f);
1612 if(prevStrs.size() == num_fields)
1613 std::swap(headerVec,prevStrs);
1620 CFile.seekg(0,std::ios::beg);
1621 CFile.getline(inBuffer,BUFFER_SIZE);
1626 num_fields=strVec.size();
1631 while(CFile.good() && !CFile.eof())
1633 if(
strhas(inBuffer,
"0123456789"))
1641 if(strVec.size() != num_fields)
1645 for(
unsigned int ui=0; ui<num_fields; ui++)
1647 if(strVec[ui] ==
"NaN" && allowNan)
1651 std::stringstream ss;
1662 dataVec[ui].push_back(f);
1669 if(!CFile.getline(inBuffer,BUFFER_SIZE))
struct AtomProbe::IONHIT IONHIT
Record as stored in a .POS file.
const char * RECORDREAD_ERR_STRINGS[]
Record as stored in a .POS file.
float flightPath
The flight path to the virtual (or real) projected tip image.
float voltage
Standing Voltage applied to specimen (V)
const char * OPS_ENUM_ERRSTRINGS[]
bool readEposRecord(const char *src, const char *dest)
const char * getPosFileErrString(unsigned int errMesg)
unsigned int loadATOFile(const char *fileName, std::vector< ATO_ENTRY > &ions, unsigned int forceEndian=0)
Load a LAWATAP "ATO" file.
std::string stripWhite(const std::string &str)
Strip whitespace, (eg tab,space) from either side of a string.
Data structure that contains the experiment information present in a 3Dap file.
bool isNotDirectory(const char *filename)
unsigned int saveTapsimBin(const std::vector< IonHit > &posIons, std::ostream &f)
Write a tapsim file from a vector of IonHits.
const char * ATO_ERR_STRINGS[]
Human readable error messages for use with ATO reader return values.
THREEDAP_DATA params
Experiment parameters.
float pulseVolt
Pulse voltage applied to specimen (V)
size_t loadEposFile(std::vector< EPOS_ENTRY > &outData, const char *filename)
Load an entire "EPOS" File.
unsigned int loadTextData(const char *cpFilename, std::vector< std::vector< float > > &dataVec, std::vector< std::string > &headerVec, const char *delim="\", bool allowNan=true, bool allowConvFails=false, unsigned int headerCount=-1)
Load a CSV, TSV or similar text file. Assumes "C" Locale for input (ie "." as decimal separator)...
unsigned int detectorChannels
The number of channels on the detector.
void setPos(const Point3D &pos)
unsigned int savePosFile(const std::vector< Point3D > &points, float mass, const char *name, bool append=false)
Save a vector of Point3Ds into a pos file, using a fixed mass, return nonzero on error.
void splitStrsRef(const char *cpStr, const char delim, std::vector< std::string > &v)
Split string references using a single delimiter.
A 3D point data class storage.
float timeOfFlight
timeOfFlight in ns. Correction status does not appear to be specified
const size_t EPOS_RECORD_SIZE
void int4SwapBytes(int32_t *inInt)
std::vector< VOLTAGE_DATA > voltageData
Voltage information.
bool getFilesize(const char *fname, size_t &size)
bool strhas(const char *cpTest, const char *cpPossible)
unsigned int fixedRecordChunkReader(const char *filename, bool(*recordReader)(const char *bufRead, const char *destBuf), size_t recordSize, std::vector< T > &outputData, unsigned int chunkSize, unsigned int chunkOffset, unsigned int &nEntriesLeft)
unsigned int readPosapOps(const char *file, THREEDAP_EXPERIMENT &data, unsigned int &badLine, unsigned int &progress, std::atomic< bool > &wantAbort, unsigned int nDelayLines=2, bool strictMode=false)
Function to read POSAP "OPS" files.
std::vector<::std::vector< SINGLE_HIT > > eventData
vector of event vectors. Each interior event vector describes a group of hits on one pulse ...
float xDetector
X and Y coordinates on the detector in mm, nominally uncorrected.
unsigned int loadPosFile(std::vector< IonHit > &posIons, const char *posFile)
Load a pos file directly into a single ion list.
unsigned int fixedRecordReader(const char *filename, bool(*recordReader)(const char *bufRead, const char *destBuf), size_t recordSize, std::vector< T > &outputData)
float tZero
Time offset for pulse, in nanoseconds.
void floatSwapBytes(float *inFloat)
float detectorRadius
The size of the detector, in mm.
float alpha
Pulse coupling coefficient (1 of 2)
float beta
Pulse coupling coefficient (2 of 2)
void setMassToCharge(float newMassToCharge)
float tof
Reported time of flight.
void randomIndices(std::vector< T > &res, size_t num, size_t nMax, gsl_rng *rng)
This is a data holding class for POS file ions, from.
float beta
Coupling coefficient to specimen.
bool stream_cast(T1 &result, const T2 &obj)
Template function to cast and object to another by the stringstream.
size_t nextHitGroupOffset
FIXME: Document me.
gsl_rng * getRng() const
Obtain a GSL random number generator.
std::vector< unsigned long long > eventPulseNumber
The pulse number associated with an event group.
void stripZeroEntries(std::vector< std::string > &s)
Voltage data structure – these updates occur periodically during the experiment. ...
unsigned int loadTapsimBinFile(vector< IonHit > &posIons, const char *posfile)
size_t chunkLoadEposFile(std::vector< EPOS_ENTRY > &outData, const char *filename, unsigned int chunkSize, unsigned int chunkOffset, unsigned int &nEntriesLeft)
Load an "EPOS" file, with a maximum chunk size.