Diana Software
QSequence.cc
Go to the documentation of this file.
1 #include "QSequence.hh"
2 #include "QBaseModule.hh"
3 #include "QReader.hh"
4 #include "QDriver.hh"
5 #include "QWriter.hh"
6 #include "QModule.hh"
7 #include "QMessage.hh"
8 #include "QOptions.hh"
9 #include "QEventAssembler.hh"
10 #include "QEventList.hh"
11 #include "QError.hh"
14 #include "QProcessStatus.hh"
15 #include "QFrameWorkConfig.hh"
16 
18 
19 size_t QSequence::fCounter = 0;
20 
21 //_____________________________________________________________________________
22 QSequence::QSequence(const std::string& n)
23  : QNamed(n), p_Reader(NULL), p_Writer(NULL), p_Driver(NULL) {
24  fCounter++;
25  fIteration = 0;
26  modules.clear();
28  fConfig.Clear();
29  fConfig.fName = n;
30 }
31 //_____________________________________________________________________________
33  // check not get params
34  if(p_Reader->isEnabled()) {
35  std::stringstream msg;
37  std::string smsg = msg.str();
38  if(!smsg.empty()) {
39  std::string s = "Sequence " + GetName();
41  }
42  // check default params
43  std::stringstream msg2;
45  smsg = msg2.str();
46  if(!smsg.empty()) {
47  std::string s = "Sequence " + GetName();
49  QMessageHandler::Get()->Send(InfoMsg,s,"Modules default parameters dumped into the logfile");
50  }
51  }
52  // delete modules
53  if(p_Reader) delete p_Reader;
54 
55  std::vector<QBaseModule*>::iterator it;
56  for( it = modules.begin(); it != modules.end(); it++)
57  delete (*it);
58 
59  if(p_Writer) delete p_Writer;
60  if(p_Driver) delete p_Driver;
61 
62  modules.clear();
63 
64  // close i/o files
68 }
69 //_____________________________________________________________________________
70 void QSequence::Dump(std::ostream& o) const {
71  o << "Sequence: " << GetName() << std::endl;
72  std::vector<QBaseModule*>::iterator it;
73  std::vector<QBaseModule*> allModules = modules;
74  if(p_Reader) allModules.insert(allModules.begin(),p_Reader);
75  if(p_Driver) allModules.push_back(p_Driver);
76  if(p_Writer) allModules.push_back(p_Writer);
77  for(it=allModules.begin(); it != allModules.end(); it++) {
78  QBaseModule *m=(*it);
79  m->UpdateEnableFlag();
80  // MV FIXME add module category
81  o << m->GetName() <<": ";
82  if (m->isEnabled())
83  o << "enabled" << std::endl;
84  else
85  o << "disabled" << std::endl;
86  }
87  o << "End of sequence: " << GetName();
88 }
89 //_____________________________________________________________________________
92  // MV FIXME fRWCommon.Clear();
93  fRunAgain = false;
94  fIteration++;
95  fConfig.fModules.clear();
96  fGlobalData.SetInputVersion(QOptions::GetInstance().GetString("General.GlobalDataInputVersion"));
97 
98  // check that all modules are of the same type
99  std::string s = "Sequence " + GetName();
100  std::vector<QBaseModule*>::iterator it;
101  if ( !p_Reader ) QMessageHandler::Get()->Send(PanicMsg,s,"Reader not defined!");
102  // build enable flag
103  std::vector<QBaseModule*> allModules = modules;
104  if(p_Reader) allModules.insert(allModules.begin(),p_Reader);
105  if(p_Driver) allModules.push_back(p_Driver);
106  if(p_Writer) allModules.push_back(p_Writer);
107  std::vector<QBaseModule*>::iterator m_iter = allModules.begin();
108  while(m_iter != allModules.end()) {
109  (*m_iter)->UpdateEnableFlag();
110  fConfig.fModules.push_back(&(*m_iter)->GetConfig());
111  m_iter++;
112  }
113  if(p_Driver && p_Driver->isEnabled()) {
114  // Driver knows modules list
115  p_Driver->SetModulesList(allModules);
116  }
119 
120  // Create event and event lists
121  QEventAssembler ev;
122  QEventList evList,oevList;
123  ev.Clear();
124  evList.Clear();
125  oevList.Clear();
126 
127  // Init
129  QMessageHandler::Get()->Send(NoFilterMsg,s,"Init modules");
130  try{
131  if ( p_Reader->isEnabled() ) p_Reader->BeginBase(ev);
132  else {
133  m_iter = allModules.begin();
134  while(m_iter != allModules.end()) {
135  (*m_iter)->Disable();
136  m_iter++;
137  }
138  QMessageHandler::Get()->Send(NoFilterMsg,s,"Reader disabled, not executing this sequence");
139  return false;
140  }
141  for( it = modules.begin(); it != modules.end(); it++ ) {
142  QBaseModule *m = (*it);
143  if ( m->isEnabled() ) m->BeginBase(ev);
144  }
145  if ( p_Driver && p_Driver->isEnabled()) p_Driver->BeginBase(ev);
146  if ( p_Writer && p_Writer->isEnabled()) p_Writer->BeginBase(ev);
147  }
148  catch(const QError& err) {
149  std::stringstream msg;
150  msg<<err;
151  QMessageHandler::Get()->Send(ErrorMsg,s,msg.str());
153  PrintGlobal();
154  else
155  PrintEvents(ev.GetEvent(),oevList);
156 
157  QMessageHandler::Get()->Send(PanicMsg,s,"Fatal error");
158  }
159  catch(...) {
160  PrintEvents(ev.GetEvent(),oevList);
161  throw;
162  }
163 
164  ev.Consolidate();
165 
166  // main loop on events
168  QMessageHandler::Get()->Send(NoFilterMsg,s,"Do modules");
170  try {
171 
172  // get events to be skipped and events to be processed
173  int NumSkip = QOptions::GetInstance().GetInt("General.EventsToBeSkipped");
174  int NumProcess = QOptions::GetInstance().GetInt("General.EventsToBeProcessed");
175 
176  // skip events at first iteration only
177  bool ret = true;
178  if ( GetIteration() == 1 ) {
179  while(NumSkip--) {
180  if (!p_Reader->ProcessBase(ev,evList,true,oevList)) {
181  ret = false;
182  break;
183  }
184  }
185  }
186 
187  //int thisProcess = NumProcess;
188  if(ret && ( (p_Driver && p_Driver->isEnabled()) ? !p_Driver->StopRun() : true)) {
189  while(dianaStatus.isRunning() && p_Reader->ProcessBase(ev,evList,true,oevList)) {
190  // manage config at first Do, not used since
191  // the object may be in the last partial
192  /*
193  if(thisProcess == NumProcess) {
194  SaveConfig();
195  }*/
196  bool ret = true;
197 
198  // run enabled modules
199  for( it = modules.begin(); it != modules.end(); it++) {
200  QBaseModule *m = (*it);
201  // modules that return false will skip subsequent modules
202 
203  if ( m->isEnabled() ) {
204  ret = m->ProcessBase(ev, evList, ret, oevList);
205  }
206  }
207 
208  if(p_Driver && p_Driver->isEnabled())
209  ret = p_Driver->ProcessBase(ev,evList,ret,oevList);
210 
211  // do writer
212  if (p_Writer && p_Writer->isEnabled()) {
213  p_Writer->ProcessBase( ev ,evList, ret,oevList);
214  }
215 
216  // check if we have processed enough events
217  NumProcess--;
218 
219  if (NumProcess == 0) break;
220  if (p_Driver && p_Driver->isEnabled() && p_Driver->StopRun()) break;
221  if(dianaStatus.HasChanged())
222  dianaStatus.Notify();
223  }
224 
225  }
226  }// try
227  catch(const QError& err) {
228  std::stringstream msg;
229  msg<<err;
230  QMessageHandler::Get()->Send(ErrorMsg,s,msg.str());
232  PrintGlobal();
233  else
234  PrintEvents(ev.GetEvent(),oevList);
235 
236  QMessageHandler::Get()->Send(PanicMsg,s,"Fatal error");
237  }
238  catch(...) {
239  PrintEvents(ev.GetEvent(),oevList);
240  throw;
241  }
242 
243  // save module config
244  SaveConfig();
245 
246  QMessageHandler::Get()->Send(NoFilterMsg,s,"Done modules");
247  // end modules
249  try {
250  p_Reader->EndBase();
251  for( it = modules.begin(); it != modules.end(); it++) {
252  QBaseModule *m = (*it);
253  if ( m->isEnabled() ) m->EndBase();
254  }
256 
257  // write module config
258  if(p_Writer && p_Writer->isEnabled()) {
259  GlobalHandle<QFrameWorkConfig> fwcHandle("Config");
260  fGlobalData.SetOwner("Diana");
261  fGlobalData.Get(&fwcHandle,"");
262  QError err = GlobalData().Set(&fwcHandle,"CurrentWriter");
263  if(err == QERR_SUCCESS) {
264  QMessageHandler::Get()->Send(InfoMsg,s,"Diana@Config saved to CurrentWriter");
265 
266  }
267  fGlobalData.SetOwner("");
268  p_Writer->EndBase();
269  }
271  }
272  catch(const QError& err) {
273  std::stringstream msg;
274  msg<<err;
275  QMessageHandler::Get()->Send(ErrorMsg,s,msg.str());
277  PrintGlobal();
278  QMessageHandler::Get()->Send(PanicMsg,s,"Fatal error");
279  }
280  catch(...) {
281  throw;
282  }
283 
284  // check diana status
285  if(dianaStatus.isError()) {
286  QMessageHandler::Get()->Send(ErrorMsg,s,dianaStatus.GetError());
287  return false;
288  }
289  if(dianaStatus.isExiting()) {
290  QMessageHandler::Get()->Send(NoFilterMsg,s,"User Interrupt detected");
291  QMessageHandler::Get()->Send(WarnMsg,s,"User Interrupt detected");
292  return false;
293  }
294 
295  return fRunAgain;
296 }
297 //_____________________________________________________________________________
299  std::vector<QBaseModule*>::iterator it;
300  std::vector<QBaseModule*> allModules = modules;
301  if(p_Driver) allModules.push_back(p_Driver);
302  if(p_Writer) allModules.push_back(p_Writer);
303 
304  std::string s = "Sequence " + GetName();
305  std::stringstream msg;
306  msg<<"Modules that needed neigbours:";
307  bool need = false;
308  for(it=allModules.begin(); it != allModules.end(); it++) {
309  QBaseModule *m=(*it);
310  if(m->NeedNeighbours()) {
311  need = true;
312  msg<<" "<<m->GetName();
313  }
314  }
315  if(!need) return;
316  if(p_Reader->NeighboursOn()) {
317  QMessageHandler::Get()->Send(DebugMsg,s,msg.str());
318  }
319  else {
320  QMessageHandler::Get()->Send(ErrorMsg,s,"Neighbours not enabled in the reader");
321  QMessageHandler::Get()->Send(ErrorMsg,s,msg.str());
322  }
323 }
324 //_____________________________________________________________________________
325 const QError& QSequence::JumpToEvent(Long64_t event, QBaseModule* caller) {
326  static QBaseModule* firstCaller = caller;
327  static QError err = QERR_UNKNOWN_ERR;
328  if(caller!=firstCaller) {
330  err.SetDescription("JumpToEvent already owned by module:" + firstCaller->GetName());
331  return err;
332  }
333  return p_Reader->BaseJumpToEvent(event);
334 }
335 //_____________________________________________________________________________
336 void QSequence::PrintEvents(const QEvent& ev, const QEventList& evList) const {
337  std::string s = "Sequence " + GetName();
338  std::stringstream estr;
339  std::string caller = "unknown";
340  if(ev.GetOwner()) caller = *ev.GetOwner();
341 
342  switch(GetSequenceStatus()){
343  case kSequenceConfig:
344  estr << "Detected error during sequence configuration \"" << caller
345  << "\". (Iteration " << GetIteration()
346  << "). Printing the event template"; break;
347  case kSequenceInit:
348  estr << "Detected error during module Init loop \"" << caller
349  << "\". (Iteration " << GetIteration()
350  << "). Printing the event template"; break;
351  case kSequenceDo:
352  estr << "Detected error in event loop, caller \"" << caller
353  << "\". (Iteration " << GetIteration()
354  << "). Printing the last event"; break;
355  default:
356  break;
357  }
358  if(!evList.Empty())
359  estr<<" and its "<<evList.Size()<<" neighbours:"<<std::endl;
360  else estr<<":"<<std::endl;
361  QMessageHandler::Get()->Send(ErrorMsg,s,estr.str());
362 
363  std::stringstream estr2;
364  estr2<<"Main Event: ";
365  ev.Dump(estr2);
366  QMessageHandler::Get()->Send(InfoMsg,s,estr2.str());
367 
368  for(size_t i = 0; i < evList.Size(); i++) {
369  std::stringstream estr;
370  estr<<"Neighbour "<<i<<": ";
371  evList[i].Dump(estr);
372  QMessageHandler::Get()->Send(InfoMsg,s,estr.str());
373  }
374 }
375 //_____________________________________________________________________________
377  std::string s = "Sequence " + GetName();
378  std::stringstream estr;
379  estr<<"Detected error in GlobalData. Printing GlobalData:"<<std::endl;
380  QMessageHandler::Get()->Send(ErrorMsg,s,estr.str());
381 
382  std::stringstream estr2;
383  fGlobalData.Dump(estr2);
384  QMessageHandler::Get()->Send(InfoMsg,s,estr2.str());
385 }
386 //_____________________________________________________________________________
387 std::string QSequence::GetReaderName() const {
388  if(p_Reader) return p_Reader->GetName();
389  else return "";
390 }
391 //_____________________________________________________________________________
392 std::string QSequence::GetWriterName() const {
393  if(p_Writer) return p_Writer->GetName();
394  else return "";
395 }
396 //_____________________________________________________________________________
397 std::string QSequence::GetDriverName() const {
398  if(p_Driver) return p_Driver->GetName();
399  else return "";
400 }
401 //_____________________________________________________________________________
403  std::string s = "Sequence " + GetName();
404  // save framework config
405  fGlobalData.SetOwner("Diana");
406 
407  GlobalHandle<QFrameWorkConfig> fwcHandle("Config");
408  fGlobalData.Get(&fwcHandle,"CurrentReader");
409 
410  QFrameWorkConfig fwc; // empty
412  QMessageHandler::Get()->Send(InfoMsg,s,"Object Diana@Config loaded from output files");
414  }
415  else if(fwcHandle.IsValid()) {
416  QMessageHandler::Get()->Send(DebugMsg,s,"Object Diana@Config loaded from input files");
417  fwc = fwcHandle.Get();
418  }
419  else {
421  QMessageHandler::Get()->Send(DebugMsg,s,"Could not find object Diana@Config from input or output files files");
422  }
423 
424  if(GetIteration() == 1 ) fwc.fSequences.push_back(&fConfig);
425  GlobalHandle<QFrameWorkConfig> fwcHandle2("Config");
426  fwcHandle2.Set(fwc);
427  QError cerr = fGlobalData.Set(&fwcHandle2,"");
428  fGlobalData.SetOwner("");
429 }
430 //_____________________________________________________________________________
431 
432 
434 
435 
err
Definition: CheckOF.C:114
#define Q_END_NAMESPACE
Definition: QDiana.hh:22
#define Q_BEGIN_NAMESPACE
Definition: QDiana.hh:20
@ QERR_GLOBAL_GENERIC
Definition: QError.hh:44
@ QERR_GLOBAL_HANDLE
Definition: QError.hh:45
@ QERR_UNKNOWN_ERR
Definition: QError.hh:108
@ QERR_SUCCESS
Definition: QError.hh:27
@ ErrorMsg
Definition: QMessageDefs.hh:9
@ DebugMsg
Definition: QMessageDefs.hh:6
@ WarnMsg
Definition: QMessageDefs.hh:8
@ PanicMsg
Definition: QMessageDefs.hh:10
@ InfoMsg
Definition: QMessageDefs.hh:7
@ NoFilterMsg
Definition: QMessageDefs.hh:11
template class to handle diana global QObject with QGlobalDataManager
const QError & GetError() const
Get I/O error.
bool IsValid() const
check QObject validity
void Set(const Q &obj)
set the QObject
const Q & Get() const
get the QObject
Base class for modules.
Definition: QBaseModule.hh:57
bool ProcessBase(QEventAssembler &ev, QEventList &evl, const bool exec, QEventList &ovl)
ProcessBase method is called for each event, getting the event and as argument.
Definition: QBaseModule.cc:128
void EndBase()
EndBase method is called after event loop.
Definition: QBaseModule.cc:162
void UpdateEnableFlag()
update enable flag
Definition: QBaseModule.hh:173
bool NeedNeighbours()
check wheter this module needs neighbours (available after the first event is processed)
Definition: QBaseModule.hh:141
void BeginBase(QEventAssembler &ev)
Begin Base method is called before event loop.
Definition: QBaseModule.cc:74
bool isEnabled() const
check if module is enabled
Definition: QBaseModule.hh:127
const std::string & GetName() const
Get Module name.
Definition: QBaseModule.hh:131
void SetModulesList(const std::vector< QBaseModule * > &modList)
method used by QSequence to set the list of modules in the QSequence
Definition: QDriver.hh:106
bool StopRun()
method used by QSequence to check if the run should be stopped
Definition: QDriver.hh:103
error class with error type and description
Definition: QError.hh:115
const std::string & GetDescription() const
get error description
Definition: QError.cc:190
Visitor class of QEvent that provides full handling of QEvent.
QEvent & GetEvent()
Get the QEvent.
void Consolidate()
Consolidate QEvent.
void Clear()
clear the underlying QEvent (calls QEvent::Clear())
list of references to const QEvent (s)
Definition: QEventList.hh:21
bool Empty() const
check if the list is empty
Definition: QEventList.hh:39
void Clear()
reset list to 0 elements
Definition: QEventList.hh:42
size_t Size() const
number of QEvent (s)
Definition: QEventList.hh:36
diana event
Definition: QEvent.hh:46
void Dump(std::ostream &o) const
Print the event and its member.
Definition: QEvent.cc:98
const std::string * GetOwner() const
get the name of the module that is currently acting on the event
Definition: QEvent.hh:277
QObject storing a set of QSecuenceConfigs.
std::vector< QSequenceConfig * > fSequences
QSequenceConfig of all sequences run on this data.
void SetOwner(const std::string &owner)
set the module that is accessing this object
void SetInputVersion(std::string versionTag)
set the version tag of the object to be read (default = this release)
void Clear()
clear cache
QError Set(GlobalHandle< Q > *gh, const std::string &outSource, bool printError=true) const
Set a QObject using a GlobalHandle.
QError Get(const std::string &owner, GlobalHandle< Q > *gh, const std::string &inSource, bool printError=true) const
Get an object using a global handle.
void Dump(std::ostream &o) const
Dump cached objects to stream.
static QGlobalReaderDispatcher & GetInstance()
static QGlobalWriterDispatcher & GetInstance()
static QMessageHandler * Get()
Definition: QMessage.cc:24
void Send(MsgLevel l, const std::string &sender, const std::string &msg)
Definition: QMessage.cc:31
base class for anything that has a name
Definition: QNamed.hh:14
const std::string & GetName() const
Definition: QNamed.hh:19
void CheckNotGet(const std::string &seq, std::ostream &o)
Definition: QOptions.cc:69
int GetInt(const std::string &seq, const std::string &mod, size_t occ, const std::string &par)
Definition: QOptions.cc:508
static QOptions & GetInstance()
Definition: QOptions.cc:23
void CheckAtDefault(const std::string &seq, std::ostream &o)
Definition: QOptions.cc:95
process status and signal handler
void Notify()
acknowledge oldest process status contained in staus queue
bool isError() const
check wether an error occurred
const std::string & GetError() const
get error string
bool HasChanged() const
tell wehter process status has changed
static QProcessStatus & GetInstance()
get singleton Instance
bool isRunning() const
check wether current process status is QRunning_s
bool isExiting() const
check wether current process status is QExiting_s
QFrameWorkConfig fFrameWorkConfigOld
Definition: QRWCommon.hh:27
QRWCommon * fRWCommon
object to share file names with QWriter
Definition: QReader.hh:108
bool NeighboursOn()
Definition: QReader.hh:84
const QError & BaseJumpToEvent(Long64_t eventnumber)
Called when another module ask for a specific event number in the next Do(), calls JumpToEvent()
Definition: QReader.cc:134
void Clear()
clear members
std::vector< QModuleConfig * > fModules
ordered modules in this sequence
std::string fName
name of this sequence
const QError & JumpToEvent(Long64_t event, QBaseModule *caller)
Jump to an event in a particular in a module.
Definition: QSequence.cc:325
QSequence(const std::string &)
Ctor that takes the name of the sequence as argument.
Definition: QSequence.cc:22
virtual ~QSequence()
Default dtor.
Definition: QSequence.cc:32
SequenceStatus GetSequenceStatus() const
Get the sequence status (Config/Init/Do/Done)
Definition: QSequence.hh:87
static size_t fCounter
Static sequence counter.
Definition: QSequence.hh:124
unsigned int GetIteration() const
Definition: QSequence.hh:83
QGlobalDataManager fGlobalData
Global variables that a module can save.
Definition: QSequence.hh:115
QDriver * p_Driver
Pointer to a driver.
Definition: QSequence.hh:110
SequenceStatus fSequenceStatus
Status of the current sequence.
Definition: QSequence.hh:130
void PrintGlobal() const
Print the global data.
Definition: QSequence.cc:376
unsigned int fIteration
Iterations counter.
Definition: QSequence.hh:118
const QGlobalDataManager & GlobalData() const
Access to the global data manager for the sequence.
Definition: QSequence.hh:65
std::vector< QBaseModule * > modules
The list of the modules.
Definition: QSequence.hh:112
void Dump(std::ostream &) const
Dump the content of the sequence.
Definition: QSequence.cc:70
std::string GetReaderName() const
Get the name of the reader.
Definition: QSequence.cc:387
QWriter * p_Writer
Pointer to the writer.
Definition: QSequence.hh:108
@ kSequenceDo
Definition: QSequence.hh:46
@ kSequenceDone
Definition: QSequence.hh:47
@ kSequenceInit
Definition: QSequence.hh:45
@ kSequenceConfig
Definition: QSequence.hh:44
QRWCommon fRWCommon
The Reader/Writer data shared between the reader and writer.
Definition: QSequence.hh:127
QReader * p_Reader
Pointer to the reader.
Definition: QSequence.hh:106
void SaveConfig()
Save the config data to file.
Definition: QSequence.cc:402
void PrintEvents(const QEvent &ev, const QEventList &evList) const
Print the event list.
Definition: QSequence.cc:336
std::string GetWriterName() const
Get the name of the writer.
Definition: QSequence.cc:392
bool Run()
The core of the sequence. Loops over Init's, Do's and Done's.
Definition: QSequence.cc:90
void CheckModuleWithNeighbours()
Check if any of the modules have neighbours.
Definition: QSequence.cc:298
QSequenceConfig fConfig
Sequence config data.
Definition: QSequence.hh:133
bool fRunAgain
Run again.
Definition: QSequence.hh:121
std::string GetDriverName() const
Get the name of the driver.
Definition: QSequence.cc:397
QRWCommon * fRWCommon
object to share file names with QReader
Definition: QWriter.hh:55