Diana Software
QFileWriter.cc
Go to the documentation of this file.
1 #include "QFileWriter.hh"
2 #include "QFileList.hh"
3 #include "QRunDataHandle.hh"
5 #include "QEventInspector.hh"
6 #include "QHeader.hh"
7 #include "TString.h"
8 #include "QPulseInfo.hh"
9 #include "QStringHandler.hh"
10 #include <TPRegexp.h>
11 #include <TObjArray.h>
12 #include <TObjString.h>
13 #include "QString.hh"
14 
15 #include <fstream>
16 #include <unistd.h>
17 #include <sys/stat.h>
18 
19 using namespace std;
20 
22 
23 std::list<std::string> QFileWriter::fFullPathFilesList;
24 //_____________________________________________________________________________
25 QFileWriter::QFileWriter( const std::string& extension) : QWriter() {
26  fFileExtension = extension;
27  fWarnRunData = true;
28  fOneFileOpenOnly = true;
29  fDoGetTower = false;
30 }
31 //_____________________________________________________________________________
33 //_____________________________________________________________________________
35  // Where to write
36  fOutputDir = GetString("OutputDir",".");
37 
38  fFileNamePrefix = GetString("OutputFilePrefix","QRFWriter_DEFAULT");
39  fFileIdentifier = GetString("FileIdentifier","SyncWithRun",true);
40  if(fFileIdentifier == "SyncWithTowerRun")
41  fDoGetTower = true;
42 
43  // Write a file list
44  fWriteFilesList = GetBool("WriteFilesList",true,false);
45  if(fWriteFilesList) {
46  fFilesListName = GetString("OutputFilesList","SyncWithRun",true);
47  if(fFilesListName == "SyncWithTowerRun")
48  fDoGetTower = true;
50  }
51 
52 
53  // If running multiple iterations, the input to the reader is the output
54  // of this writer
55  fSetListForReader = GetBool("SetListForReader",true,false);
56  // If running multiple iterations, save the intermediary files.
57  fSaveTempFiles = GetBool("SaveTempFiles",false,false);
58  if(!fSaveTempFiles)
59  fNewPartialOnRerun = GetBool("NewPartialOnRerun",false,false);
60  else
61  fNewPartialOnRerun = false;
62  // Store the framework config
63  fKeepFrameWorkConfig = GetBool("KeepFrameWorkConfig",false,false);
64 
65  // Open a new file for each run
66  fSyncWithRun = GetBool("SyncWithRun",true, false);
67 
68  // Open a new partial each time the reader does
69  fSyncWithReader = GetBool("SyncWithReader",true,false);
70  if(!fSyncWithReader ) {
71  // If not syncing with reader, find out how many to write before
72  // starting a new partial
73  fPartialSize = GetInt("PartialSize",0);
74  if(fPartialSize < 0)
75  Panic("PartialSize cannot be < 0 (Read %d)",fPartialSize);
76  }
77 
78  // If source of the event is cached, then use it. Otherwise it will
79  // fall back to fRWCommon->fCurrentReaderFileName
82  "OriginFileName");
83 
84  fEventNumber = 0;
85  if(GetIteration() > 1 && fNewPartialOnRerun) return;
86  fFilesList.clear();
87  fFullPathFilesList.clear();
88  fCurrentRun = -999999;
89  fPartial = 0;
90 
91  // set this writer for global writers
92  std::stringstream currentWriterForGlobal;
93  currentWriterForGlobal<<Q_CURRENT_WRITER<<fFileExtension;
95  SetCurrentWriterFilename(currentWriterForGlobal.str());
96  Require(evi);
97  if(fDoGetTower)
98  evi.GetEvent().Require<QPulseInfo>("DAQ","PulseInfo");
99 }
100 //_____________________________________________________________________________
102 
103 
104  if(IsToOpen(evi.GetEvent())) {
105  // MV FIXME use event objects set by instead of RunData
106  ReadHandle<QHeader> hh("Header");
107  evi.GetEvent().Get("DAQ",hh);
108  int run = 0;
109  if(hh.IsValid()) run = hh.Get().GetRun();
110  else Warn("No Header found, run number in filenames will be \"0\"");
111  // Get the run type
112  QRunDataHandle rHandle(run);
113  GlobalData().Get<QRunData>("",&rHandle,"");
114 // char runType = 'U';
115 
116  if(rHandle.IsValid()) {
117  const QRunData& runData = rHandle.Get();
118  run = runData.fNumber;
119  // runType = runData.fType.AsString().at(0);
120  } else if(fWarnRunData) {
121  Warn("No RunData found, run type in filenames will be \"Unknown\"");
122  Warn("No RunData found, tower in filenames will be 0");
123  fWarnRunData = false;
124  }
125 
126  // If we are on a new run, reset the partial
127  if(fSyncWithRun && run != fCurrentRun){
128  fPartial = 0;
129  fPartialsByFileId.clear();
130  }
131  fCurrentRun = run;
132 
133  // Close the previous files
134  if(fFilesList.size() > 0 && fOneFileOpenOnly ) {
135  Debug("Closing %s",fFullPathFilesList.back().c_str());
136  Close();
137  }
138 
139  // Build the new file names
140  BuildFileName(evi.GetEvent());
141 
142  // Write the file list (why do we write it here, before adding the
143  // new file?)
144  if(fWriteFilesList)
145  WriteFilesList();
146  // fFileName = fFileNamePrefix +"_" + fFileId + fFileExtension;
148 
149  // Check that there is a FrameWorkConfig before overwriting
152  GlobalHandle<QFrameWorkConfig> fwcHandle("Config");
153  dm.Get("Diana",&fwcHandle,fFileFullPath);
154  if(fwcHandle.IsValid()) {
155  Debug("Found valid FrameworkConfig");
156  fRWCommon->fFrameWorkConfigOld = fwcHandle.Get();
157  }
158  }
159  // Open the new file
160  Open(fFileFullPath, evi);
161  Info("Current file is %s",fFileFullPath.c_str());
162  fFilesList.push_back(fFileName);
164  }
165  // Write to the tree
166  Dump(evi);
167  fEventNumber++;
168 }
169 //_____________________________________________________________________________
171  if(fFilesList.size() > 0 ) {
172  Debug("Closing %s",fFullPathFilesList.back().c_str());
173  Close();
174  }
175  Debug("Number of events written %d",fEventNumber);
176  std::list<std::string>::iterator filesListIter;
177  if(GetRunAgain() && fNewPartialOnRerun) return;
178 
179  // Run again on sequence needs files for temporary events so we
180  // rename the existing ones
181  if(GetRunAgain()){
182  char iterBuf[4], pidBuf[32];
183  snprintf(iterBuf,4,"%.2d",GetIteration());
184  snprintf(pidBuf,32,"%d",getpid());
185  for(filesListIter = fFilesList.begin();
186  filesListIter != fFilesList.end(); filesListIter++) {
187  std::string fileName = *filesListIter;
188  std::string tempFileName = std::string(iterBuf) + "_" + *filesListIter ;
189  // moving output files to temp files
190  rename((fOutputDir + "/" + fileName).c_str(),
191  (fOutputDir + "/" + tempFileName).c_str());
192  *filesListIter = tempFileName;
193  }
194  if(fWriteFilesList) remove(fCurrFilesListName.c_str());
195  fCurrFilesListName = fOutputDir + "/" + std::string(pidBuf) + "_"
196  + std::string(iterBuf) + "_"
197  + fFileNamePrefix + ".list";
198  if(fSetListForReader)
200  }
201 
202  // write list file
204  WriteFilesList();
205 
206  // remove files of previous iterations if not requested
207  if(GetIteration() > 1 && !fSaveTempFiles) {
208  for(filesListIter = fOldFilesList.begin();
209  filesListIter != fOldFilesList.end(); filesListIter++) {
210  std::string toBeRemoved = fOutputDir + "/" + *filesListIter;
211  Debug("Removing %s", toBeRemoved.c_str());
212  remove(toBeRemoved.c_str());
213  }
214  remove(fOldFilesListName.c_str());
215  Debug("Removing %s", fOldFilesListName.c_str());
216  }
217 
220 }
221 //_____________________________________________________________________________
224  int FilePermissions = strtol(GetString("FilePermissions","0644",false).c_str(),NULL,8);
225  chmod(fCurrFilesListName.c_str(),FilePermissions);
226 }
227 //_____________________________________________________________________________
229  if(fWriteFilesList) remove(fCurrFilesListName.c_str());
230 }
231 //_____________________________________________________________________________
232 bool QFileWriter::IsToOpen(const QEvent& ev) const {
233  // MV FIXME use event objects set by instead of RunData
234  ReadHandle<QHeader> hh("Header");
235  ev.Get("DAQ",hh);
236 
237  int run = 0;
238  if(hh.IsValid()) run = hh.Get().GetRun();
239  else Warn("No Header found, run number in filenames will be \"0\"");
240 
241  bool retVal = false;
242  if(fSyncWithReader) {
243  if(fRWCommon->fReaderFileNumber > (int)fFilesList.size() ) {
244  retVal = true;
245  }
246  }
247  else if (fPartialSize == 0) {
248  if(fCurrentRun < 0)
249  retVal = true;
250  else
251  retVal = false;
252  }
253  else if (fEventNumber % fPartialSize == 0)
254  retVal = true;
255  if(fSyncWithRun && run != fCurrentRun)
256  retVal = true;
257  return retVal;
258 }
259 //_____________________________________________________________________________
260 const std::string &QFileWriter::GetCorrespondingReaderFileName(const QEvent &ev) const {
261  std::string &readerFileName = fRWCommon->fReaderCurrentFileName;
263  readerFileName =
264  ev.Get<Diana::QString>(fRWCommon->fReaderModuleName.c_str(),"OriginFileName");
265  return readerFileName;
266 }
267 //_____________________________________________________________________________
269 
271  GlobalData().Get<QRunData>("",&rHandle,"");
272  char runType = 'U';
273  int tower = 0;
274  if(rHandle.IsValid()) {
275  const QRunData& runData = rHandle.Get();
276  runType = runData.fType.AsString().at(0);
277  } else if(fWarnRunData) {
278  Warn("No RunData found, run type in filenames will be \"Unknown\"");
279  Warn("No RunData found, tower in filenames will be 0");
280  fWarnRunData = false;
281  }
282 
283  if(fDoGetTower) {
284  ReadHandle<QPulseInfo> ph("PulseInfo");
285  ev.Get("DAQ",ph);
286  /*
287  int channel = Q_INT_DEFAULT;
288  if(ph.IsValid()) channel = ph.Get().GetChannelId();
289  QDetChannelCollectionHandle dccHandle;
290  dccHandle.SetRun(fCurrentRun);
291  GlobalData().Get("",&dccHandle,"");
292  if(dccHandle.IsValid()) {
293  const QDetChannel &detChannel = dccHandle.Get().Get(channel);
294  tower = detChannel.fTd.fTdTower;
295  }
296  else
297  */
298  if(fWarnRunData) {
299 
300  Warn("No RunData found, tower in filenames will be 0");
301  }
302  }
303  Bool_t usingPartial=true;
304  if(fFileIdentifier == "SyncWithRun" || fFileIdentifier=="") {
305  fFileId = Form("%06d_%c",fCurrentRun,runType);
306  }
307  else if(fFileIdentifier == "SyncWithTowerRun") {
308  fFileId = Form("%06d_%03d_%c",fCurrentRun,tower,runType);
309  }
310  else if(fFileIdentifier == "Random"){
312  usingPartial = false;
313  }
314  else if(fFileIdentifier == "SyncWithReader") {
315  static TPRegexp Re("_([0-9]+(_[0-9]+)?_[A-Z]_p[0-9]{3})");
316  TObjArray *matches = Re.MatchS(fRWCommon->fReaderCurrentFileName);
317  if(matches->GetEntries()>0){
318  fFileId = ((TObjString *)matches->At(1))->GetString().Data();
319  }
320  else {
322  Warn("Could not parse reader file name for file ID! Will use random string"
323  " identifier %s -> %s.",
324  fRWCommon->fReaderCurrentFileName.c_str(),fFileId.c_str());
325  }
326  delete matches;
327  usingPartial=false;
328  }
329  else if (fFileIdentifier != "") {
331  }
332  else
333  Panic("No valid file identifier provided! Output files will not be uniquely named!");
334 
335  if(usingPartial){
336  fFileId+=Form("_p%03d",IncrementPartial(fFileId));
337  }
339 
340  if(fFilesListName == "SyncWithRun" || fFilesListName=="") {
342  Form("%s/%s_%06d_%c.list",fOutputDir.c_str(),fFileNamePrefix.c_str(),
343  fCurrentRun,runType);
344  }
345  else if(fFilesListName == "SyncWithTowerRun") {
347  Form("%s/%s_%06d_%03d_%c.list",fOutputDir.c_str(),fFileNamePrefix.c_str(),
348  fCurrentRun,tower,runType);
349  }
350 }
351 //_____________________________________________________________________________
352 int QFileWriter::IncrementPartial(const std::string &fileId) {
353  if(!fPartialsByFileId.count(fileId))
354  fPartialsByFileId[fileId]=0;
355  int &partial=fPartialsByFileId[fileId];
356  return ++partial;
357 }
358 
QRunDataHandle rHandle(753)
QGlobalDataManager dm
double Re(const Diana::QComplex &z)
Function to get the real part.
Definition: QComplex.cc:260
#define Q_CURRENT_WRITER
Definition: QDiana.hh:40
#define Q_END_NAMESPACE
Definition: QDiana.hh:22
#define Q_BEGIN_NAMESPACE
Definition: QDiana.hh:20
template class to handle diana global QObject with QGlobalDataManager
bool IsValid() const
check QObject validity
const Q & Get() const
get the QObject
const std::string & GetString(const std::string &parname, const std::string &defVal, bool warnCfg=true) const
Get a string parameter from config file ( see GetDouble() )
Definition: QBaseModule.cc:297
void Debug(const char *descr,...) const
Send a debug message (used to debug the module) with printf syntax.
Definition: QBaseModule.hh:208
void Warn(const char *descr,...) const
Send a warning message (an error that the framework can recover) with printf syntax.
Definition: QBaseModule.hh:228
unsigned int GetIteration() const
Get Current sequence iteration.
Definition: QBaseModule.hh:122
void Info(const char *descr,...) const
Send an info message (information) with printf syntax.
Definition: QBaseModule.hh:218
bool GetRunAgain() const
Check if the sequence will be reiterated.
Definition: QBaseModule.hh:118
void Panic(const char *descr,...) const
Send a panic message (stops the framework) with printf syntax.
Definition: QBaseModule.hh:248
int GetInt(const std::string &parname, int defVal, bool warnCfg=true) const
Get an int parameter from config file ( see GetDouble() )
Definition: QBaseModule.cc:219
bool GetBool(const std::string &parname, bool defVal, bool warnCfg=true) const
Get a bool parameter from config file ( see GetDouble() )
Definition: QBaseModule.cc:256
const QGlobalDataManager & GlobalData() const
interface for saving and loading global QObjects
Definition: QBaseModule.hh:116
Visitor class to inspect the QEvent content.
QEvent & GetEvent()
Get the event.
diana event
Definition: QEvent.hh:46
void Require(const std::string &owner, const std::string &name) const
notify the QEvent that we need a QObject, if not found an exception is thrown
Definition: QEvent.hh:232
void Get(const char *owner, ReadHandle< Q > &handle) const
Get a QObject Handle in read mode.
Definition: QEvent.hh:74
bool Contains(const char *owner, const char *name) const
Check to see if the event contains a particular object.
Definition: QEvent.hh:279
void Write(const std::string &fileListPath) const
Definition: QFileList.cc:45
std::string fOutputDir
Directory that we are writing to.
Definition: QFileWriter.hh:191
std::string fFileIdentifier
The file identifier (follows the prefix)
Definition: QFileWriter.hh:213
int fEventNumber
current event number
Definition: QFileWriter.hh:105
std::string fFileNamePrefix
filename components
Definition: QFileWriter.hh:185
void WriteFilesList()
write list of files
Definition: QFileWriter.cc:222
std::string fFileName
fFileName = fFileNamePrefix + fFileId
Definition: QFileWriter.hh:189
std::map< std::string, int > fPartialsByFileId
Current partial file for a given file ID.
Definition: QFileWriter.hh:239
std::string fFilesListName
Definition: QFileWriter.hh:195
int fPartial
Partial number that we are currently working on.
Definition: QFileWriter.hh:227
virtual void Init(QEventInspector &evi)
Init method called by the framework.
Definition: QFileWriter.cc:34
virtual void BuildFileName(const QEvent &evi)
Definition: QFileWriter.cc:268
bool fDoGetTower
Flag to get the tower from the current event.
Definition: QFileWriter.hh:225
std::list< std::string > fFilesList
List of the full paths of files opened.
Definition: QFileWriter.hh:180
virtual const std::string & GetCorrespondingReaderFileName(const Diana::QEvent &ev) const
Get the file from which this event was read.
Definition: QFileWriter.cc:260
int fPartialSize
Partial size. When reached, automatically create a new file.
Definition: QFileWriter.hh:219
virtual void Done()
Done method called by the framework.
Definition: QFileWriter.cc:170
virtual bool IsToOpen(const Diana::QEvent &ev) const
Test to see if a new file needs to be opened.
Definition: QFileWriter.cc:232
virtual void Require(const QEventInspector &evi)
optional method to set required QObjects, called before Open
Definition: QFileWriter.hh:75
bool fSaveTempFiles
Flag to say whether we save the temporary files created.
Definition: QFileWriter.hh:217
bool fWarnRunData
If the run data is not valid, pass a warning.
Definition: QFileWriter.hh:235
bool fSetListForReader
Definition: QFileWriter.hh:207
virtual void Do(QEventInspector &evi)
Do method called by the framework.
Definition: QFileWriter.cc:101
bool fOneFileOpenOnly
Can the writer open more than one file at a time?
Definition: QFileWriter.hh:233
std::string fCurrFilesListName
Name of the file list for this iteration.
Definition: QFileWriter.hh:211
QFileWriter(const std::string &extension)
constructor
Definition: QFileWriter.cc:25
std::string fFileFullPath
fFileFullPath = fOutputDir + "/" + fFileName + fFileExtension
Definition: QFileWriter.hh:193
bool fSyncWithReader
Flag to synchronize the output files with the input.
Definition: QFileWriter.hh:221
std::string fOldFilesListName
Name of the file list written in the previous iteration.
Definition: QFileWriter.hh:209
bool fKeepFrameWorkConfig
Write the Sequence config data to the file.
Definition: QFileWriter.hh:237
static std::list< std::string > fFullPathFilesList
List of the full paths of files opened by all writers.
Definition: QFileWriter.hh:178
virtual void Open(const std::string &filename, const QEventInspector &evi)=0
Open File.
int fCurrentRun
Current run being worked on.
Definition: QFileWriter.hh:229
virtual void Close()=0
Close file.
std::list< std::string > fOldFilesList
List of files opened on the previous iteration.
Definition: QFileWriter.hh:182
virtual int IncrementPartial(const std::string &fileId)
Definition: QFileWriter.cc:352
bool fNewPartialOnRerun
Does rerunning the sequence create new files, or a new partial.
Definition: QFileWriter.hh:231
std::string fFileId
End of the file name to be tacked on to the prefix.
Definition: QFileWriter.hh:187
std::string fFileExtension
file extension
Definition: QFileWriter.hh:108
virtual void Dump(const QEventInspector &evi)=0
Dump ev to file.
bool fSyncWithRun
Flag to start a new file for each new run.
Definition: QFileWriter.hh:223
bool fUseEventCachedFileName
Flag to determine whether to use the file in the event cache.
Definition: QFileWriter.hh:204
bool fWriteFilesList
Flag whether we are writing a files list.
Definition: QFileWriter.hh:215
void RemoveFilesList()
remove list of files
Definition: QFileWriter.cc:228
virtual ~QFileWriter()
destructor
Definition: QFileWriter.cc:32
Object to manage I/O (DB, file, or memory) of diana global quantities.
QError Get(const std::string &owner, GlobalHandle< Q > *gh, const std::string &inSource, bool printError=true) const
Get an object using a global handle.
static QGlobalWriterDispatcher & GetInstance()
virtual bool IsValid() const
Check object validity.
Definition: QHandle.hh:34
Raw event: bolometer channel, trigger positions and types.
Definition: QPulseInfo.hh:18
QFrameWorkConfig fFrameWorkConfigOld
Definition: QRWCommon.hh:27
int fReaderFileNumber
Definition: QRWCommon.hh:18
std::string fReaderCurrentFileName
Definition: QRWCommon.hh:19
std::string fTempOutputFileList
Definition: QRWCommon.hh:20
std::string fReaderModuleName
Definition: QRWCommon.hh:25
global handle for QRunData
Basic run based info.
Definition: QRunData.hh:20
int fNumber
Run Number.
Definition: QRunData.hh:41
RunType fType
Run Type.
Definition: QRunData.hh:45
string wrapped into a QObject
Definition: QString.hh:18
Abstract class for diana writers.
Definition: QWriter.hh:30
QRWCommon * fRWCommon
object to share file names with QReader
Definition: QWriter.hh:55
read handle to access QEvent QObject's.
Definition: QHandle.hh:126
const T & Get() const
Get Object.
Definition: QHandle.hh:133
std::string AsString() const
convert to string
Definition: QRunType.hh:64
std::string RandomString(UInt_t length, Bool_t caseSensitive=true, Bool_t startLetter=false)
Return a random string of lenght.