25#if __cplusplus >= 201402L
26# define MKCODAFILE make_unique<Decoder::THaCodaFile>()
28# define MKCODAFILE unique_ptr<Decoder::THaCodaFile>(new Decoder::THaCodaFile)
36#if ROOT_VERSION_CODE < ROOT_VERSION(6,22,0)
38 if( !pathname || !strchr(pathname,
'/') )
41 auto pathlen = strlen(pathname);
43 const char*
r = pathname + pathlen - 1;
45 while( (
r > pathname) && (*
r ==
'/') )
48 while( (
r > pathname) && (*
r !=
'/') )
53 while( (
r > pathname) && (*
r ==
'/') )
57 if( (
r == pathname) && (*
r !=
'/') )
60 return TString(pathname,
r + 1 - pathname);
71 return base + (base.
EndsWith(
"/") ?
"" :
"/") + to_join;
75static inline string JoinPath(
const string& base,
const string& to_join )
79 return base + (base[base.length()-1] ==
'/' ?
"" :
"/") + to_join;
84 const char* description,
bool is_regex )
91 , fNameIsRegexp{is_regex}
98 if( filenamePattern && *filenamePattern )
110 const char* filenamePattern,
const char* description,
113 vector<string>{(filenamePattern ? filenamePattern :
"")},
114 description, is_regex)
119 const char* description,
bool is_regex )
121 , fFileList{
std::move(fileList)}
122 , fPathList{
std::move(pathList)}
128 , fNameIsRegexp{is_regex}
129 , fLastUsedStream{-1}
148 , fFileList{rhs.fFileList}
149 , fPathList{rhs.fPathList}
150 , fStreams{rhs.fStreams}
151 , fFirstSegment{rhs.fFirstSegment}
152 , fFirstStream{rhs.fFirstStream}
153 , fMaxSegments{rhs.fMaxSegments}
154 , fMaxStreams{rhs.fMaxStreams}
156 , fNameIsRegexp{rhs.fNameIsRegexp}
157 , fLastUsedStream{-1}
177 const auto& mfr =
dynamic_cast<const MultiFileRun&
>(rhs);
188 catch(
const std::bad_cast& ) {
207 bool doing_init = (sopt.
Contains(
"INIT"));
235 Int_t st = stream.Close();
249 if (
this == obj)
return 0;
250 const auto* rhs =
dynamic_cast<const THaRunBase*
>(obj);
251 if( !rhs )
return -1;
253 if( *
this < *rhs )
return -1;
254 else if( *rhs < *
this )
return 1;
255 const auto* mfr =
dynamic_cast<const MultiFileRun*
>(rhs);
257 if(
fStreams > mfr->fStreams )
return 1;
258 if( fStreams < mfr->
fStreams )
return -1;
279 cerr <<
"Not open" << endl;
283 cerr <<
"No events read" << endl;
291 assert(curstr.fActive);
292 if( !curstr.fActive ) {
294 cerr <<
"At EOF" << endl;
297 return curstr.GetEvBuffer();
307 assert(curstr.fActive);
308 if( !curstr.fActive )
310 return curstr.fEvNum;
325 if( data_ver == 0 ) {
327 }
else if( ver != data_ver ) {
329 cerr <<
"Inconsistent CODA version " << ver <<
" for file "
330 << path <<
", expected " << data_ver << endl;
336 cerr <<
"Error getting CODA version from file " << path << endl;
351 assert(!stream.fFiles.empty());
352 for(
const auto&
file: stream.fFiles ) {
358 else if(
file.fStem != stem ) {
359 cerr <<
"Warning: Inconsistent file naming: \"" <<
file.fStem
360 <<
"\" vs. \"" << stem <<
". Are these the same runs?" << endl;
362 assert(stream.fCodaData);
363 Int_t ret = stream.fCodaData->codaOpen(
file.fPath.c_str());
365 cerr <<
"Error " << ret <<
" opening CODA file " <<
file.fPath << endl;
368 file.fPath, stream.fCodaData->getCodaVersion(), file_data_version);
376 assert(file_data_version > 0);
381 cerr <<
"One or more files had errors" << endl;
391 Int_t seg = -1, str = -1;
398 return ifo.
fID == str;
404 auto& files = it->fFiles;
405 auto jt = find_if(ALL(files), [seg](
const FileInfo& fi ) {
408 if( jt == files.end() )
409 files.emplace_back(path.
Data(), stem.
Data(), seg);
411 if( jt->fStem == stem ) {
412 cerr <<
"Warning: Duplicate segment number: "
413 << jt->fPath <<
" : " << path << endl
414 <<
"Ignoring apparently identical file " << path << endl;
416 cerr <<
"Error: Duplicate segment number: "
417 << jt->fPath <<
" : " << path << endl
418 <<
"Files seem different, check your filename pattern." << endl;
441 auto& files = stream.fFiles;
445 nfiles += files.size();
447 cout <<
"MultiFileRun: " << nfiles <<
" file";
448 if( nfiles != 1 ) cout <<
's';
449 cout <<
" in " <<
fStreams.size() <<
" stream";
450 if(
fStreams.size() != 1 ) cout <<
's';
459 while( dirn !=
"/" && dirn !=
"." ) {
463 vs.emplace_back(dirn);
477 cerr <<
"Warning: Directory " << itempath
478 <<
" is not accessible. Check permissions." << endl;
510 string spath = str.
Data();
514 return spath.find_first_of(
"?*[") != string::npos;
518 auto is_regex_char = []( string::value_type
c ) {
519 return (
c ==
'.' ||
c ==
'[' ||
520 c ==
'*' ||
c ==
'+' ||
c ==
'?');
522 string::size_type pos = 0;
524 pos = spath.find_first_of(
"^$.[*+?\\", pos);
525 if( pos == string::npos )
528 if( is_regex_char(
c) )
534 if( (
c ==
'^' && pos == 0) || (
c ==
'$' && pos + 1 == spath.length()) )
538 if(
c ==
'\\' && pos + 1 < spath.length()
539 && is_regex_char(spath[pos + 1]) )
552 cerr <<
"Directory " << dir <<
" unexpectedly cannot be opened." << endl;
557 bool found_exact =
false;
559 if( strcmp(entry,
".") == 0 || strcmp(entry,
"..") == 0 )
564 ret = action(dir, item);
586 const TString& dir = path.first;
591 cerr <<
"Bad filename pattern \"" <<
file <<
"\", err = "
592 << file_re.
Status() << endl;
598 return action(dir,
file);
604 (
const TString& curdir,
const std::vector<TString>& splitpath,
Int_t level,
605 bool regex_mode,
const action_t& action )
607 auto do_directory = [
this, level, &splitpath, &action]
610 auto itempath =
JoinPath(curpath, subdir);
612 return DescendInto(itempath, splitpath, level + 1, action);
613 }
else if( !TestBit(kResolvingWildcard) ) {
614 cerr << itempath <<
" is not a directory" << endl;
619 const auto& subdir = splitpath[level];
620 if( HasWildcards(subdir) ) {
621 TRegexp subdir_re(subdir, !regex_mode);
623 cerr <<
"Bad directory pattern \"" << subdir <<
"\", err = "
624 << subdir_re.
Status() << endl;
627 return ForEachMatchItemInDir(curdir, subdir_re, do_directory);
629 return do_directory(curdir, subdir);
635 (
const TString& curpath,
const std::vector<TString>& splitpath,
Int_t level,
638 if( level+1 >= SSIZE(splitpath) ) {
640 return ScanForFilename({curpath, splitpath[level]}, fNameIsRegexp, action);
642 return ScanForSubdirs(curpath, splitpath, level, fNameIsRegexp, action);
652 splitpath.push_back(path.second);
653 assert(!splitpath.empty());
654 const auto topdir = splitpath[0];
675 const vector<string>& file_list )
687 for(
const auto&
file: file_list ) {
688 if(
file.empty() ||
file.front() !=
'/' )
696 bool temp_pathlist =
false;
698 temp_pathlist =
true;
706 for(
const auto&
file: file_list ) {
707 if(
file.empty() ||
file.front() ==
'/' )
714 if( std::find(ALL(candidates), cand_path) == candidates.end() )
715 candidates.emplace_back(std::move(cand_path));
734 vector<path_t> candidates;
745 cerr << itempath <<
" is a directory. Expected file." << endl;
752 set<TString> files_found;
753 for(
const auto& path: candidates ) {
754 if( files_found.find(path.second) != files_found.end() )
770 files_found.insert(path.second);
777 cerr <<
"MultiFileRun::Open: no matching files found" << endl;
799 cerr <<
"CODA file name not set. Cannot open the run." << endl;
835 cerr <<
"Not open" << endl;
852 Int_t st = curstr.Read();
854 curstr.fActive =
false;
878 for(
Int_t i = 0; i < sz; ++i ) {
880 if( stream.fActive && stream.fEvNum < minev ) {
882 minev = stream.fEvNum;
885 assert(minidx != -1);
891 for(
int i = 0; i < sz; ++i ) {
921 return initinfo_file;
925 vector<string> file_list;
926 bool have_empty =
false;
933 file_list.push_back(
JoinPath(fdir,base));
935 if( file_list.empty() || have_empty )
936 file_list.push_back(base);
941 vector<path_t> candidates;
945 auto set_filename = [&initinfo_file](
const TString& curpath,
951 initinfo_file = itempath;
954 cerr << itempath <<
" is a directory. Expected file." << endl;
960 initinfo_file.
Clear();
961 for(
const auto& path: candidates ) {
973 assert(!initinfo_file.
IsNull());
979 return initinfo_file;
990 << ( !files.empty() ? files[0].c_str() :
"(not set)" ) <<
"\"";
991 if( files.size() > 1 )
992 cout <<
" etc. (" << files.size() <<
" files)";
994 cout <<
" \"" <<
GetTitle() <<
"\"";
999 cout <<
"Search path";
1001 cout <<
"s:" << endl;
1005 cout <<
" " << path << endl;
1024 cout <<
"File name";
1035 cout <<
" " <<
file << endl;
1043 for(
const auto& stream:
fStreams ) {
1044 if( stream.fID >= 0 )
1045 cout <<
"Stream " << stream.fID;
1047 cout <<
"Default stream";
1048 cout <<
": " << endl;
1049 for(
const auto&
file: stream.fFiles ) {
1050 cout <<
" " <<
file.fPath << endl;
1071 static const char*
const here =
"MultiFileRun::SetFilename";
1087 catch( std::invalid_argument&
e ) {
1088 cerr <<
e.what() << endl;
1109 for_each(ALL(filelist), expand_name);
1111 catch( std::invalid_argument&
e ) {
1112 cerr <<
e.what() << endl;
1129 for_each(ALL(pathlist), expand_name);
1131 catch( std::invalid_argument&
e ) {
1132 cerr <<
e.what() << endl;
1191 assert(curstr.fFileIndex < SSIZE(curstr.fFiles));
1192 fSegment = curstr.fFiles[curstr.fFileIndex].fSegment;
1203 cerr <<
"MultiFileRun: Warning: file name " <<
file
1204 <<
" is an absolute path, but path list also specified. "
1205 "Will ignore path list for this file." << endl;
1220 string s =
"MultiFileRun: Undefined environment variable in path \"";
1221 s.append(str).append(
"\"");
1222 throw std::invalid_argument(s);
1231 for(
const auto& stream:
fStreams ) {
1232 nfiles += stream.fFiles.size();
1247 for(
const auto& stream:
fStreams ) {
1248 for(
const auto&
file: stream.fFiles ) {
1249 if(
file.fSegment < minseg )
1250 minseg =
file.fSegment;
1260 for(
const auto& stream:
fStreams ) {
1261 for(
const auto&
file: stream.fFiles ) {
1262 if(
file.fSegment > maxseg )
1263 maxseg =
file.fSegment;
1273 for(
const auto& stream:
fStreams ) {
1274 if( stream.fID < minstr )
1275 minstr = stream.fID;
1284 for(
const auto& stream:
fStreams ) {
1285 if( stream.fID > maxstr )
1286 maxstr = stream.fID;
1294 vector<string> files;
1295 for(
const auto& stream:
fStreams ) {
1296 for(
const auto&
file: stream.fFiles ) {
1297 files.push_back(
file.fPath);
1345 if(
this != &rhs ) {
1383 cerr <<
"Not open" << endl;
1401 cout <<
"MultiFileRun::Read: Switching to next segment idx = "
1442 auto evlen = evbuf[0] + 1;
1444 cerr <<
"Physics event too short, len = " << evlen <<
", need >= 5"
1448 if( evbuf[4] <= num )
1449 cerr <<
"MultiFileRun::FetchEventNumber: Warning: unexpected "
1450 <<
"event number change " << num <<
" -> " << evbuf[4]
1462 auto block_size = evbuf[1] & 0xff;
1463 if( block_size == 0 ) {
1464 cerr <<
"CODA 3 format error: Physics event with block size 0" << endl;
1470 tbank.
Fill(evbuf + 2, block_size,
1475 cerr <<
"CODA 3 format error: " <<
e.what() << endl;
1478 if( tbank.
evtNum <= num )
1479 cerr <<
"MultiFileRun::FetchEventNumber: Warning: unexpected "
1480 <<
"event number change " << num <<
" -> " << tbank.
evtNum
1495 cerr <<
"Invalid event buffer size = 0" << endl;
1498 const auto* evbuf =
fCodaData->getEvBuffer();
1499 auto evlen = evbuf[0] + 1;
1500 if( evlen > buflen ) {
1501 cerr <<
"Invalid event length " << evlen
1502 <<
" > buffer size " << buflen << endl;
1506 cerr <<
"Event too short, len = " << evlen <<
", need >= 2" << endl;
1509 auto tag = evbuf[1] >> 16;
1527 cerr <<
"Unsupported CODA version " <<
fVersion << endl;
1536 static const string nullstr;
std::vector< FileInfo > fFiles
Coda data (file)
Int_t OpenCurrent()
Stream has not yet reached EOF.
UInt_t fEvNum
Index of currently open file.
Bool_t fActive
Number of most recent physics event.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize id
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
static const char *const here
Bool_t R_ISDIR(Int_t mode)
R__EXTERN TSystem * gSystem
uint32_t Fill(const uint32_t *evbuffer, uint32_t blkSize, uint32_t tsroc)
static UInt_t InterpretBankTag(UInt_t tag)
virtual Bool_t IsOpen() const
void AssembleFilePaths(std::vector< path_t > &candidates)
Int_t ForEachMatchItemInDir(const TString &dir, const TRegexp &match_re, const action_t &action)
std::pair< TString, TString > path_t
void PrintStreamInfo() const
virtual Int_t FindNextStream() const
Int_t GetLastSegment() const
virtual UInt_t GetEvNum() const
bool SetPathList(std::vector< std::string > pathlist)
UInt_t GetNStreams() const
void SetFirstSegment(Int_t n)
virtual void Clear(Option_t *opt="")
void SetMaxStreams(Int_t n)
std::vector< std::string > GetFiles() const
UInt_t fNevRead
Number of active streams.
MultiFileRun(const char *filenamePattern="", const char *description="", bool is_regex=false)
virtual Int_t BuildInputList()
Number of events read.
virtual Int_t ReadEvent()
bool CheckWarnAbsFilename()
Int_t CheckFilesConsistency()
void PrintFileInfo() const
Int_t ScanForFilename(const path_t &path, bool regex_mode, const action_t &action)
Int_t BuildInputListFromWildcardDir(const path_t &path, const action_t &action)
std::vector< std::string > fFileList
void SetMaxSegments(Int_t n)
virtual void Print(Option_t *opt="") const
virtual Int_t GetDataVersion()
std::vector< StreamInfo > fStreams
std::function< Int_t(const TString &, const TString &)> action_t
bool SetFileList(std::vector< std::string > filelist)
Int_t ScanForSubdirs(const TString &curdir, const std::vector< TString > &splitpath, Int_t level, bool regex_mode, const action_t &action)
Int_t AddFile(const TString &file, const TString &dir)
Int_t GetLastStream() const
Int_t GetStartStream() const
Int_t BuildInputListFromTopDir(const path_t &path, const action_t &action)
bool HasWildcards(const TString &str) const
virtual Int_t SetFilename(const char *name)
virtual const UInt_t * GetEvBuffer() const
std::vector< std::string > fPathList
Int_t GetStartSegment() const
virtual Bool_t FindSegmentNumber()
void SetFirstStream(Int_t n)
virtual Int_t Compare(const TObject *obj) const
Int_t DescendInto(const TString &curpath, const std::vector< TString > &splitpath, Int_t level, const action_t &action)
MultiFileRun & operator=(const THaRunBase &rhs)
void ExpandFileName(std::string &str) const
Int_t fNActive
Index of last stream that was read.
virtual TString FindInitInfoFile(const TString &fname)
std::unique_ptr< Decoder::THaCodaData > fCodaData
static Int_t ReturnCode(Int_t coda_retcode)
Bool_t Contains(const std::string &token) const
virtual TString GetInitInfoFileName(TString fname)
virtual void Clear(Option_t *opt="")
static Bool_t StdFindSegmentNumber(const TString &filename, TString &stem, Int_t &segment, Int_t &stream)
virtual THaRun & operator=(const THaRunBase &rhs)
const char * GetTitle() const override
void Print(Option_t *option="") const override
virtual void Error(const char *method, const char *msgfmt,...) const
Ssiz_t Index(const TString &str, Ssiz_t *len, Ssiz_t start=0) const
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
const char * Data() const
virtual void FreeDirectory(void *dirp)
virtual void * OpenDirectory(const char *name)
virtual int GetPathInfo(const char *path, FileStat_t &buf)
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
virtual const char * GetDirEntry(void *dirp)
virtual const char * BaseName(const char *pathname)
virtual char * ExpandPathName(const char *path)
virtual TString GetDirName(const char *pathname)
static const UInt_t MAX_PHYS_EVTYPE
static vector< TString > SplitPath(const TString &path)
static bool item_exists(const TString &itempath)
static bool item_is_not_dir(const TString &itempath)
static TString JoinPath(const TString &base, const TString &to_join)
static bool item_is_dir(const TString &itempath)
static Int_t GetEvNumV2(const UInt_t *evbuf, UInt_t &num)
static TString GetDirName(const char *pathname)
static Int_t CheckSetFileDataVersion(const string &path, Int_t ver, Int_t &data_ver)
static Int_t GetEvNumV3(const UInt_t *evbuf, UInt_t &num)
const std::string & GetFilename() const
Bool_t fActive
Number of most recent physics event.
Int_t OpenCurrent()
Stream has not yet reached EOF.
StreamInfo & operator=(const StreamInfo &rhs)
UInt_t fEvNum
Index of currently open file.
std::vector< FileInfo > fFiles
Coda data (file)
const UInt_t * GetEvBuffer() const