EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Fun4AllDstPileupInputManager.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file Fun4AllDstPileupInputManager.cc
1 
8 
10 #include <fun4all/Fun4AllServer.h>
11 
12 #include <ffaobjects/RunHeader.h>
13 
14 #include <frog/FROG.h>
15 
16 #include <phool/PHCompositeNode.h>
17 #include <phool/PHNodeIOManager.h>
18 #include <phool/PHNodeIntegrate.h>
19 #include <phool/PHNodeIterator.h> // for PHNodeIterator
20 #include <phool/PHRandomSeed.h>
21 #include <phool/getClass.h>
22 #include <phool/phool.h> // for PHWHERE, PHReadOnly, PHRunTree
23 
24 #include <gsl/gsl_randist.h>
25 
26 #include <cassert>
27 #include <iostream> // for operator<<, basic_ostream, endl
28 #include <utility> // for pair
29 
30 //_____________________________________________________________________________
31 Fun4AllDstPileupInputManager::Fun4AllDstPileupInputManager(const std::string &name, const std::string &nodename, const std::string &topnodename)
32  : Fun4AllInputManager(name, nodename, topnodename)
33 {
34  // initialize random generator
35  const uint seed = PHRandomSeed();
36  m_rng.reset( gsl_rng_alloc(gsl_rng_mt19937) );
37  gsl_rng_set( m_rng.get(), seed );
38 }
39 
40 //_____________________________________________________________________________
41 int Fun4AllDstPileupInputManager::fileopen(const std::string &filenam)
42 {
43  /*
44  this is largely copied from fun4all/Fun4AllDstInputManager::fileopen
45  with additional code to handle the background IManager
46  */
47 
48  auto se = Fun4AllServer::instance();
49  if (IsOpen())
50  {
51  std::cout << "Closing currently open file "
52  << FileName()
53  << " and opening " << filenam << std::endl;
54  fileclose();
55  }
56  FileName(filenam);
57  FROG frog;
59  if (Verbosity() > 0)
60  {
61  std::cout << Name() << ": opening file " << m_fullfilename << std::endl;
62  }
63  // sanity check - the IManager must be nullptr when this method is executed
64  // if not something is very very wrong and we must not continue
65  assert( !m_IManager );
66 
67  // first read the runnode if not disabled
68  if (m_ReadRunTTree)
69  {
71  if (m_IManager->isFunctional())
72  {
73  m_runNode = se->getNode(m_RunNode, TopNodeName());
74  m_IManager->read(m_runNode);
75 
76  // get the current run number
77  auto runheader = findNode::getClass<RunHeader>(m_runNode, "RunHeader");
78  if (runheader)
79  {
80  SetRunNumber(runheader->get_RunNumber());
81  }
82  // delete our internal copy of the runnode when opening subsequent files
83  assert( !m_runNodeCopy );
84  m_runNodeCopy.reset(new PHCompositeNode("RUNNODECOPY"));
85  if (!m_runNodeSum)
86  {
87  m_runNodeSum.reset(new PHCompositeNode("RUNNODESUM"));
88  }
89 
90  {
91  // read run node using temporary node iomanager
93  }
94 
95  PHNodeIntegrate integrate;
96  integrate.RunNode(m_runNode);
97  integrate.RunSumNode(m_runNodeSum.get());
98  // run recursively over internal run node copy and integrate objects
99  PHNodeIterator mainIter(m_runNodeCopy.get());
100  mainIter.forEach(integrate);
101  // we do not need to keep the internal copy, keeping it would crate
102  // problems in case a subsequent file does not contain all the
103  // runwise objects from the previous file. Keeping this copy would then
104  // integrate the missing object again with the old copy
105  m_runNodeCopy.reset();
106  }
107  // DLW: move the delete outside the if block to cover the case where isFunctional() fails
108  m_IManager.reset();
109  }
110 
111  // create internal dst node
112  if (!m_dstNodeInternal)
113  {
114  m_dstNodeInternal.reset(new PHCompositeNode("DST_INTERNAL"));
115  }
116 
117  // update dst node from fun4all server
118  m_dstNode = se->getNode(InputNode(), TopNodeName());
119 
120  // open file in both active and background input manager
122  if (m_IManager->isFunctional())
123  {
124  IsOpen(1);
125  m_ievent_thisfile = 0;
126  setBranches(); // set branch selections
127  AddToFileOpened(FileName()); // add file to the list of files which were opened
128  return 0;
129  }
130  else
131  {
132  std::cout << PHWHERE << ": " << Name() << " Could not open file " << FileName() << std::endl;
133  m_IManager.reset();
134  return -1;
135  }
136 }
137 
138 //_____________________________________________________________________________
140 {
141 
142  if( nevents == 0 ) return runOne( nevents );
143  else if( nevents > 1 )
144  {
145  const auto result = runOne( nevents-1 );
146  if( result != 0 ) return result;
147  }
148 
149  /*
150  * assign/create relevant dst nodes if not already there
151  * this normally happens in ::fileopen however, when the file is not oppened during first event, for instance because background rate is too low,
152  * this can cause fun4all server to bark with "Someone changed the number of Output Nodes on the fly"
153  */
154  if( !m_dstNode )
155  {
156  auto se = Fun4AllServer::instance();
157  m_dstNode = se->getNode(InputNode(), TopNodeName());
158  }
159 
160  if (!m_dstNodeInternal)
161  {
162  m_dstNodeInternal.reset(new PHCompositeNode("DST_INTERNAL"));
163  }
164 
165  // create merger node
166  Fun4AllDstPileupMerger merger;
167  merger.load_nodes(m_dstNode);
168 
169  // generate background collisions
170  const double mu = m_collision_rate*m_time_between_crossings*1e-9;
171 
172  const int min_crossing = m_tmin/m_time_between_crossings;
173  const int max_crossing = m_tmax/m_time_between_crossings;
174  for( int icrossing = min_crossing; icrossing <= max_crossing; ++icrossing )
175  {
176  const double crossing_time = m_time_between_crossings * icrossing;
177  const int ncollisions = gsl_ran_poisson(m_rng.get(), mu);
178  for (int icollision = 0; icollision < ncollisions; ++icollision)
179  {
180 
181  // read one event
182  const auto result = runOne( 1 );
183  if( result != 0 ) return result;
184 
185  // merge
186  if (Verbosity() > 0)
187  {
188  std::cout << "Fun4AllDstPileupInputManager::run - merged background event " << m_ievent_thisfile << " time: " << crossing_time << std::endl;
189  }
190  merger.copy_background_event(m_dstNodeInternal.get(), crossing_time);
191 
192  }
193  }
194 
195  return 0;
196 }
197 
198 //_____________________________________________________________________________
200 {
201  if (!IsOpen())
202  {
203  std::cout << Name() << ": fileclose: No Input file open" << std::endl;
204  return -1;
205  }
206  m_IManager.reset();
207  IsOpen(0);
208  UpdateFileList();
209  return 0;
210 }
211 
212 //_____________________________________________________________________________
213 int Fun4AllDstPileupInputManager::BranchSelect(const std::string &branch, const int iflag)
214 {
215  int myflag = iflag;
216  // if iflag > 0 the branch is set to read
217  // if iflag = 0, the branch is set to NOT read
218  // if iflag < 0 the branchname is erased from our internal branch read map
219  // this does not have any effect on phool yet
220  if (myflag < 0)
221  {
222  std::map<const std::string, int>::iterator branchiter;
223  branchiter = m_branchread.find(branch);
224  if (branchiter != m_branchread.end())
225  {
226  m_branchread.erase(branchiter);
227  }
228  return 0;
229  }
230 
231  if (myflag > 0)
232  {
233  if (Verbosity() > 1)
234  {
235  std::cout << "Setting Root Tree Branch: " << branch << " to read" << std::endl;
236  }
237  myflag = 1;
238  }
239  else
240  {
241  if (Verbosity() > 1)
242  {
243  std::cout << "Setting Root Tree Branch: " << branch << " to NOT read" << std::endl;
244  }
245  }
246  m_branchread[branch] = myflag;
247  return 0;
248 }
249 
250 //_____________________________________________________________________________
252 {
253  if (m_IManager)
254  {
255  if (!m_branchread.empty())
256  {
257  std::map<const std::string, int>::const_iterator branchiter;
258  for (branchiter = m_branchread.begin(); branchiter != m_branchread.end(); ++branchiter)
259  {
260  m_IManager->selectObjectToRead(branchiter->first.c_str(), branchiter->second);
261  if (Verbosity() > 0)
262  {
263  std::cout << branchiter->first << " set to " << branchiter->second << std::endl;
264  }
265  }
266  }
267  }
268  else
269  {
270  std::cout << PHWHERE << " " << Name() << ": You can only call this function after a file has been opened" << std::endl;
271  std::cout << "Do not worry, the branches will be set as soon as you open a file" << std::endl;
272  return -1;
273  }
274  return 0;
275 }
276 
277 //_____________________________________________________________________________
278 void Fun4AllDstPileupInputManager::Print(const std::string &what) const
279 {
280  if (what == "ALL" || what == "BRANCH")
281  {
282  // loop over the map and print out the content (name and location in memory)
283  std::cout << "--------------------------------------" << std::endl
284  << std::endl;
285  std::cout << "List of selected branches in Fun4AllDstPileupInputManager " << Name() << ":" << std::endl;
286 
287  std::map<const std::string, int>::const_iterator iter;
288  for (iter = m_branchread.begin(); iter != m_branchread.end(); ++iter)
289  {
290  std::cout << iter->first << " is switched ";
291  if (iter->second)
292  {
293  std::cout << "ON";
294  }
295  else
296  {
297  std::cout << "OFF";
298  }
299  std::cout << std::endl;
300  }
301  }
302  if ((what == "ALL" || what == "PHOOL") && m_IManager)
303  {
304  // loop over the map and print out the content (name and location in memory)
305  std::cout << "--------------------------------------" << std::endl
306  << std::endl;
307  std::cout << "PHNodeIOManager print in Fun4AllDstPileupInputManager " << Name() << ":" << std::endl;
308  m_IManager->print();
309  }
311  return;
312 }
313 
314 //_____________________________________________________________________________
316 {
317  if (m_IManager)
318  {
319  unsigned EventOnDst = m_IManager->getEventNumber();
320  EventOnDst -= static_cast<unsigned>(i);
321  m_ievent_thisfile -= i;
322  m_ievent_total -= i;
323  m_IManager->setEventNumber(EventOnDst);
324  return 0;
325  }
326  std::cout << PHWHERE << Name() << ": could not push back events, Imanager is NULL"
327  << " probably the dst is not open yet (you need to call fileopen or run 1 event for lists)" << std::endl;
328  return -1;
329 }
330 
331 //_____________________________________________________________________________
333 {
334  if (!IsOpen())
335  {
336  if (FileListEmpty())
337  {
338  if (Verbosity() > 0)
339  {
340  std::cout << Name() << ": No Input file open" << std::endl;
341  }
342  return -1;
343  }
344  else
345  {
346  if (OpenNextFile())
347  {
348  std::cout << Name() << ": No Input file from filelist opened" << std::endl;
349  return -1;
350  }
351  }
352  }
353  if (Verbosity() > 3)
354  {
355  std::cout << "Getting Event from " << Name() << std::endl;
356  }
357 
358 readagain:
359 
360  // read main event to dstNode
361  auto dummy = m_IManager->read(m_dstNodeInternal.get());
362  int ncount = 0;
363  while (dummy)
364  {
365  ++ncount;
366  if (nevents > 0 && ncount >= nevents)
367  {
368  break;
369  }
370  dummy = m_IManager->read(m_dstNodeInternal.get());
371  }
372  if (!dummy)
373  {
374  fileclose();
375  if (!OpenNextFile())
376  {
377  goto readagain;
378  }
379  return -1;
380  }
381  m_ievent_total += ncount;
382  m_ievent_thisfile += ncount;
383  // check if the local SubsysReco discards this event
385  {
386  goto readagain;
387  }
388  return 0;
389 }