StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StMuChainMaker.cxx
1 /***************************************************************************
2  *
3  * $Id: StMuChainMaker.cxx,v 1.31 2008/10/19 21:35:55 tone421 Exp $
4  * Author: Frank Laue, BNL, laue@bnl.gov
5  *
6  **************************************************************************/
7 #include <fstream>
8 
9 #include "StMuException.hh"
10 #include "StMuDebug.h"
11 #include "StMuChainMaker.h"
12 #include "StMuDbReader.h"
13 #include "StMuTimer.h"
14 
15 #include "StMaker.h"
16 #include "StChain.h"
17 
18 #include "TFile.h"
19 #include "TTree.h"
20 #include "TChain.h"
21 #include "TSystem.h"
22 #include "StMessMgr.h"
23 
24 extern TSystem* gSystem;
25 
26 string StMuChainMaker::mSQLConnection ="";
27 
28 ClassImp(StMuChainMaker)
29 //-----------------------------------------------------------------------
30 //-----------------------------------------------------------------------
31 //-----------------------------------------------------------------------
35  StMuChainMaker::StMuChainMaker(const char* name) : mTreeName(name) {
36  DEBUGMESSAGE2("");
37  mChain = new TChain(mTreeName.c_str());
38  mChain->SetDirectory(0);
39  mDbReader = StMuDbReader::instance();
40  mFileCounter=0;
41  // mSubFilters = new string[100];
42 }
43 //-----------------------------------------------------------------------
44 //-----------------------------------------------------------------------
45 //-----------------------------------------------------------------------
51  DEBUGMESSAGE2("");
52  // delete []mSubFilters;
53 }
54 //-----------------------------------------------------------------------
55 //-----------------------------------------------------------------------
56 //-----------------------------------------------------------------------
61 string StMuChainMaker::buildFileName(string dir, string fileName, string extention){
62  DEBUGMESSAGE2("");
63  fileName = dir + fileName + extention;
64  return fileName;
65 }
66 //-----------------------------------------------------------------------
67 //-----------------------------------------------------------------------
68 //-----------------------------------------------------------------------
73 string StMuChainMaker::basename(string s){
74  string name(s);
75  size_t pos;
76  pos = name.find_last_of("/");
77  if (pos!=string::npos ) name.erase(0, pos+1 );
78  pos = name.find_first_of(".");
79  if (pos!=string::npos ) name.erase(pos,name.length() );
80  DEBUGVALUE2(name);
81  return name;
82 }
83 //-----------------------------------------------------------------------
84 //-----------------------------------------------------------------------
85 //-----------------------------------------------------------------------
91 string StMuChainMaker::dirname(string s){
92  string name(s);
93  string base(basename(s));
94  name.erase(name.find(base),base.length());
95  size_t pos;
96  pos = name.find_last_of("/");
97  if (pos!=string::npos ) name.erase(pos, name.length());
98  if (name=="/") name = "";
99  DEBUGVALUE2(name);
100  return name;
101 }
102 //-----------------------------------------------------------------------
103 //-----------------------------------------------------------------------
104 //-----------------------------------------------------------------------
126 TChain* StMuChainMaker::make(string dir, string file, string filter, int maxFiles) {
127  DEBUGMESSAGE1("");
128  mMaxFiles = maxFiles;
129  subFilter(filter);
130 
131  string dirFile = dir+file;
132  DEBUGVALUE1(dir.c_str());
133  DEBUGVALUE1(file.c_str());
134  DEBUGVALUE1(dirFile.c_str());
135 
136  if (dirFile.find(".lis")!=string::npos) fromList(dirFile);
137  else if (dirFile.find(".files")!=string::npos) fromList(dirFile);
138  else if (dirFile.find(".MuDst.root")!=string::npos) fromFile(dirFile);
139  else if (dirFile.rfind("/") == dirFile.length()-1 ) fromDir(dirFile);
140  else {
141  FORCEDDEBUGMESSAGE("ATTENTION: don't know how to read input (you may have used a bogus constructor syntax)");
142  return NULL;
143  }
144 
145  if ( mFileList.size() == 0 ) {
146  DEBUGMESSAGE("No files found");
147  return 0;
148  }
149 
150  add( mFileList );
151 
152  DEBUGMESSAGE2("return");
153  return mChain;
154 }
155 //-----------------------------------------------------------------------
156 //-----------------------------------------------------------------------
157 //-----------------------------------------------------------------------
158 void StMuChainMaker::subFilter(string filter) {
159  DEBUGMESSAGE2("");
160  string tmp(filter);
161  int n=0;
162  size_t pos=0;
163  while ( tmp.length() ) {
164  DEBUGMESSAGE3("");
165  DEBUGVALUE3(tmp);
166  DEBUGVALUE3(string::npos);
167  pos = tmp.find_first_of(":");
168  if ( pos==string::npos ) pos = tmp.length();
169  mSubFilters[n] = string( tmp.substr(0,pos) );
170  DEBUGVALUE3(mSubFilters[n]);
171  tmp.erase(0,pos+1);
172  DEBUGVALUE3(tmp);
173  n++;
174  }
175  mSubFilters[n] = string("endOfFilters");
176  DEBUGMESSAGE2("return");
177 }
178 //-----------------------------------------------------------------------
179 //-----------------------------------------------------------------------
180 //-----------------------------------------------------------------------
181 void StMuChainMaker::add( StMuStringLongPairVector fileList ) {
182  DEBUGMESSAGE3("");
183  // if no entries in db, just add file
184 
185  StMuStringLongPairVectorIterator iter;
186  for ( iter=fileList.begin(); iter!=fileList.end(); iter++) {
187  if (mFileCounter>=mMaxFiles) break;
188  add( *iter );
189  }
190 }
191 
192 //-----------------------------------------------------------------------
193 //-----------------------------------------------------------------------
194 //-----------------------------------------------------------------------
196 void StMuChainMaker::add( StMuStringLongPair filenameEvents) {
197  string file = filenameEvents.first;
198  int entries = filenameEvents.second;
199 
200  string rootdTag = "root://";
201  // if this is a rootd file, check whether you are on the corresponding host
202  //cout << file.c_str() << endl;
203  if ( file.find(rootdTag)==0 ) {
204  // get local machine name
205  string machine(gSystem->HostName());
206 
207  //if (machine.find("rcas")!=string::npos) machine += ".rcf.bnl.gov";
208  //if (machine.find("rcrs")!=string::npos) machine += ".rcf.bnl.gov";
209  //if (machine.find("pdsf")!=string::npos) machine += ".nersc.gov";
210  //cout << machine.c_str() << endl;
211  // get name of machine holding the file
212  int pos = file.find("//",rootdTag.length());
213  string node = file.substr(rootdTag.length(),pos-rootdTag.length());
214  //cout << node.c_str() << endl;
215  if ( node == machine ) {
216  LOG_INFO << " filename changed from " << file.c_str();
217  file.erase(0,pos+1);
218  LOG_INFO << " to : " << file.c_str() << endm;
219  }
220  }
221 
222  if (entries==0 || entries==TChain::kBigNumber) { // try to read the number of event from the db reader
223  int tmp_entries = mDbReader->entries(file.c_str());
224  if (tmp_entries != 0)
225  entries = tmp_entries;
226  else
227  entries = TChain::kBigNumber; // If still not known, set to kBigNumber to avoid opening of file
228  }
229  // If entries==0, TChain will open the file and get the number of entries
230  // If entries==TChain::kBigNumber, TChain will start reading
231  // and figure out the numbers of events while going along
232  mChain->Add( file.c_str(), entries );
233  mFileCounter++;
234 }
235 //-----------------------------------------------------------------------
236 //-----------------------------------------------------------------------
237 //-----------------------------------------------------------------------
238 void StMuChainMaker::fromDir(string dir) {
239  DEBUGMESSAGE2("");
240  DEBUGVALUE2(gSystem);
241 
242  void *pDir = gSystem->OpenDirectory(dir.c_str());
243  // now find the files that end in the specified extention
244  const char* fileName(0);
245  while((fileName = gSystem->GetDirEntry(pDir))){
246  bool good = true;
247  string name(fileName);
248  if( strcmp(fileName,".")==0 || strcmp(fileName,"..")==0) good=false;
249  if( strcmp(fileName,".root")==0 || strcmp(fileName,"..")==0) good=false;
250  if ( name.find(".MuDst.root")==string::npos ) good=false;
251  if ( good && pass(name,mSubFilters) ) {
252  char* fullFile = gSystem->ConcatFileName(dir.c_str(),fileName);
253  // add it to the list of files
254  const auto TChain_kBigNumber = TChain::kBigNumber; // https://github.com/root-project/root/issues/9422
255  mFileList.push_back( StMuStringLongPair( fullFile, TChain_kBigNumber ) );
256  delete []fullFile;
257  }
258  }
259 }
260 //-----------------------------------------------------------------------
261 //-----------------------------------------------------------------------
262 //-----------------------------------------------------------------------
263 #include "TSQLServer.h"
264 #include "TSQLResult.h"
265 #include "TSQLRow.h"
267  DEBUGMESSAGE2("");
268  TSQLServer* server = TSQLServer::Connect(mSQLConnection.c_str(),"","");
269  if ( !server ) DEBUGMESSAGE("could not connect to server");
270 
272  string machine(gSystem->Getenv("HOSTNAME"));
273  //if (machine.find(".rcf.bnl.gov")==string::npos) machine += ".rcf.bnl.gov";
274 
276  string files("(filename='dummy')");
277  ifstream in(list.c_str());
278  if (!in) {
279  DEBUGMESSAGE("can not open file");
280  DEBUGVALUE(list);
281  return;
282  }
283  char line[512];
284  while ( in.getline(line,511) ) {
285  string full(line);
286  int split = full.rfind("/");
287  string name = full.substr(split+1);
288  string path = full.substr(0,split);
289  DEBUGVALUE(path);
290  DEBUGVALUE(name);
291  if (path.find("/star/data")==0) { // if it's NFS disk
292  files += " || (filePath='" + path + "'&&fileName='" + name +"')";
293  }
294  else { // if it's a local disk, then add the maschine to the querey
295  files += " || (filePath='" + path + "'&&fileName='" + name + "'&&nodeName='" + machine + "')";
296  }
297  }
298  in.close();
299 
300  DEBUGVALUE(files);
301 
302  // now query the database
303  StMuTimer timer;
304  timer.stop();
305  timer.reset();
306  string query = "SELECT filePath,fileName,numEntries FROM FileData LEFT JOIN FileLocations USING (fileDataId) WHERE " + files;
307  DEBUGVALUE2(query.c_str());
308  TSQLResult* result = server->Query(query.c_str());
309  timer.stop();
310 
311  DEBUGVALUE(timer.elapsedTime());
312  DEBUGVALUE(result->GetRowCount());
313 
314  // now fill chain with query results
315  TSQLRow* row;
316  string file;
317  int entries;
318  while ( (row=result->Next()) ) {
319  file = row->GetField(0);
320  file += +"/";
321  file += row->GetField(1);
322  entries = atoi(row->GetField(2));
323  mFileList.push_back( StMuStringLongPair(file, entries ));
324  }
325 
326  server->Close();
327  delete server;
328  DEBUGVALUE2(mFileCounter);
329 }
330 //-----------------------------------------------------------------------
331 //-----------------------------------------------------------------------
332 //-----------------------------------------------------------------------
333 void StMuChainMaker::fromList(string list) {
334  DEBUGMESSAGE2("");
335  ifstream inputStream(list.c_str());
336  if (!(inputStream.good())) {
337  LOG_ERROR << "ERROR: Cannot open list file " << list << endm;
338  }
339  char line[512];
340  char name[500];
341  string ltest;
342  DEBUGVALUE(inputStream.good());
343  while (inputStream.good()) {
344  inputStream.getline(line,512);
345  string ltest(line);
346  if (inputStream.good()) {
347  Long_t numberOfEvents = TChain::kBigNumber;
348  int iret = sscanf(line,"%s%i",name, &numberOfEvents);
349  if(iret) {/*warnOff*/}
350  if ( pass(name,mSubFilters) && ltest!="") {
351  mFileList.push_back( StMuStringLongPair( name, numberOfEvents) );
352  }
353  }
354  }
355 }
356 //-----------------------------------------------------------------------
357 //-----------------------------------------------------------------------
358 //-----------------------------------------------------------------------
359 void StMuChainMaker::fromFile(string file) {
360  DEBUGMESSAGE2("");
361  DEBUGMESSAGE2(mTreeName.c_str());
362  const auto TChain_kBigNumber = TChain::kBigNumber; // https://github.com/root-project/root/issues/9422
363  mFileList.push_back( StMuStringLongPair( file, TChain_kBigNumber ) );
364 }
365 //-----------------------------------------------------------------------
366 //-----------------------------------------------------------------------
367 //-----------------------------------------------------------------------
368  bool StMuChainMaker::pass(string file, string* filters) {
369  bool good = true;
370  int n=0;
371  while (filters[n].find("endOfFilters")==string::npos && good) {
372  if ( StMuDebug::level()==3 ) printf("%s %s %d ",file.c_str(),filters[n].c_str(), file.find(filters[n])==string::npos);
373  if ( (file.find(filters[n])==string::npos) ) good=false;
374  if ( StMuDebug::level()==3 ) printf("good= %d \n",good);
375  n++;
376  }
377  DEBUGVALUE3(good);
378  return good;
379  }
380  /***************************************************************************
381  *
382  * $Log: StMuChainMaker.cxx,v $
383  * Revision 1.31 2008/10/19 21:35:55 tone421
384  * Code added in StMuChainMaker::fromList(string list) to ensure blank lines are ignored when they occur in the filelist paased to the StMuDstMaker constructor.
385  *
386  * Revision 1.30 2008/07/15 18:22:34 jeromel
387  * Replace GetEnv by HostName()
388  *
389  * Revision 1.29 2007/08/02 18:57:49 mvl
390  * One more change to avoid reading all input files on initialisation: If the number of events is '0' for a given file, set it to TChain::kBigNumber.
391  *
392  * Revision 1.28 2007/05/16 18:50:49 mvl
393  * Cleanup of output. Replaced cout with LOG_INFO etc.
394  *
395  * Revision 1.27 2006/12/20 21:53:15 mvl
396  * Added warning when file list not found (read mode)
397  *
398  * Revision 1.26 2006/06/22 23:30:55 mvl
399  * Minor change to prevent reading all files during initialisation.
400  * Files ar enow added with TChain::Add(filename,kBigNumber) if no event count is available.
401  *
402  * Revision 1.25 2005/10/06 01:30:30 mvl
403  * Changed some of the logic in StMuChainMaker: Now files are no longer opened
404  * and checked at the start of the job, but simply added to the TChain. TChain
405  * automatically skips corrupted files (this is a new feature).
406  *
407  * Revision 1.24 2004/04/09 21:09:27 jeromel
408  * Did not think of wildcards ...
409  *
410  * Revision 1.23 2004/04/08 23:58:39 jeromel
411  * Used to crash on opening file if zero size. Corrected
412  *
413  * Revision 1.22 2004/02/17 04:56:36 jeromel
414  * Extended help, added crs support, restored __GNUC__ for PRETTY_FUNCTION(checked once
415  * more and yes, it is ONLY defined in GCC and so is __FUCTION__), use of a consistent
416  * internal __PRETTYF__, return NULL if no case selected (+message) and protected against
417  * NULL mChain.
418  *
419  * Revision 1.21 2003/08/04 18:43:19 perev
420  * warnOff
421  *
422  * Revision 1.20 2003/04/28 14:02:49 laue
423  * Reversed faulty check in from Friday. Reading directories should work again
424  *
425  * Revision 1.19 2003/04/24 22:22:11 laue
426  * Bug fixed when reading directories. Forgot the string terminator when
427  * searching for the last character.
428  *
429  * Revision 1.18 2003/04/21 18:18:52 laue
430  * Modifications for the new scheduler implementation:
431  * - the filenames and the number of events per files are now supplied
432  * - files on local disk are given in the rootd format
433  *
434  * Revision 1.17 2003/04/15 16:15:29 laue
435  * Minor changes to be able to filter MuDst.root files and an example
436  * how to do this. The StMuDstFilterMaker is just an example, it has to be
437  * customized (spoilers, chrome weels, etc.) by the user.
438  *
439  * Revision 1.16 2003/03/19 18:58:04 laue
440  * StMuChainMaker: updates for moved file catalog
441  * StTriggerIdCollection added to the createStEvent function in StMuDst.cxx
442  *
443  * Revision 1.15 2003/03/06 01:34:18 laue
444  * StAddRunInfoMaker is a make helper maker to add the StRunInfo for the
445  * only year1 Au+Au 130GeV data
446  *
447  * Revision 1.14 2003/01/22 13:49:12 laue
448  * debug message removed
449  *
450  * Revision 1.13 2003/01/10 16:37:37 laue
451  * Bug fix for FileCatalog look-up. Don't require machine for NFS files on
452  * /star/data... . I know a hard-wired string this is not the nice way to do
453  * it, I'll improve this once I find the time.
454  *
455  * Revision 1.12 2002/12/31 19:52:11 laue
456  * bug fix in built of filters
457  *
458  * Revision 1.11 2002/12/19 19:44:25 laue
459  * update to read number of events from database, for files ending with .list
460  *
461  * Revision 1.10 2002/11/27 20:37:02 laue
462  * output removed
463  *
464  * Revision 1.9 2002/11/18 14:29:31 laue
465  * update for Yuri's new StProbPidTraits
466  *
467  * Revision 1.8 2002/10/01 23:46:13 laue
468  * setting all unused subFilters explicitly to NULL
469  *
470  * Revision 1.7 2002/08/27 21:20:07 laue
471  * Fei Du's request
472  * fileCouter>maxFiles changed to fileCounter>=maxFiles
473  * Now maxFiles and not maxFiles+1 are added to the list
474  *
475  * Revision 1.6 2002/08/20 19:55:48 laue
476  * Doxygen comments added
477  *
478  * Revision 1.5 2002/05/04 23:56:29 laue
479  * some documentation added
480  *
481  * Revision 1.4 2002/04/17 21:04:15 laue
482  * minor updates
483  *
484  * Revision 1.3 2002/04/15 22:18:15 laue
485  * bug fix in reading of single file
486  *
487  * Revision 1.2 2002/04/11 14:19:30 laue
488  * - update for RH 7.2
489  * - decrease default arrays sizes
490  * - add data base readerfor number of events in a file
491  *
492  * Revision 1.1 2002/04/01 22:42:29 laue
493  * improved chain filter options
494  *
495  *
496  **************************************************************************/
497 
498 
499 
500 
501 
502 
503 
504 
505 
506 
507 
508 
509 
510 
511 
512 
513 
514 
string dirname(string)
virtual ~StMuChainMaker()
void fromFileCatalog(string file)
int entries(const char *file)
scan internal data base for file, if found return number of entries, otherwise return 0; ...
TChain * make(string dir, string file, string filter, int maxFiles=10)
static int level()
returns debug level
Definition: StMuDebug.h:78
string basename(string)
string buildFileName(string dir, string fileName, string extention)