SLIC  6.1.1
Simulation for the Linear Collider (SLIC) - Geant4 simulation application
LcioManager.cc
Go to the documentation of this file.
1 #include "LcioManager.hh"
2 
3 // SLIC
4 #include "EventSourceManager.hh"
5 #include "FileUtil.hh"
6 #include "LcioFileNamer.hh"
7 #include "LcioMessenger.hh"
8 #include "PackageInfo.hh"
9 #include "RunManager.hh"
10 #include "SlicApplication.hh"
11 #include "StdHepEventSource.hh"
12 #include "TimeUtil.hh"
13 
14 // LCDD
15 #include "lcdd/core/LCDDProcessor.hh"
16 #include "lcdd/hits/CalorimeterHit.hh"
17 #include "lcdd/hits/TrackerHit.hh"
18 #include "lcdd/util/StringUtil.hh"
19 
20 // LCIO
21 #include "EVENT/LCIO.h"
22 #include "IMPL/LCCollectionVec.h"
23 #include "IO/LCWriter.h"
24 #include "IOIMPL/LCFactory.h"
25 #include "UTIL/LCTOOLS.h"
26 #include "UTIL/lStdHep.hh"
27 
28 // Geant4
29 #include "G4EventManager.hh"
30 #include "G4Run.hh"
31 #include "G4RunManager.hh"
32 #include "G4SDManager.hh"
33 #include "G4TrajectoryContainer.hh"
34 #include "G4VHitsCollection.hh"
35 
36 // STL
37 #include <ctime>
38 
39 using EVENT::LCIO;
40 using EVENT::MCParticle;
41 using IMPL::LCCollectionVec;
42 using IMPL::LCEventImpl;
43 using IMPL::LCRunHeaderImpl;
44 using UTIL::LCTOOLS;
45 using UTIL::lStdHep;
46 
47 using std::string;
48 
49 namespace slic {
50 
51 string LcioManager::m_defaultFileName = "slicEvents";
52 
54  Module("LcioManager"), m_writer(NULL), m_runHdr(NULL), m_fileExistsAction(LcioManager::eFail), m_runNumber(0), m_enableDumpEvent(false), m_writerIsOpen(false), m_usingAutoname(false) {
55 
56  // Initialize the Geant4 UI messenger for the LCIO.
57  m_messenger = new LcioMessenger(this);
58 
59  // Initialize the LCIO HitsCollectionBuilder.
61 
62  // Create the LCIO writer.
63  createWriter();
64 
65  // Create the LCIO file namer.
66  m_namer = new LcioFileNamer();
67 
68  // Set the default output file name.
70 }
71 
73 
74  deleteWriter();
75 
76  if (m_messenger != 0) {
77  delete m_messenger;
78  }
79 }
80 
82 
83  // Get full output path with extension to check its existence.
84  string fullFilename = getFullOutputPath(true);
85 
86  // Default to writing a new file.
87  int writeMode = LCIO::WRITE_NEW;
88 
89  // File exists?
90  if (FileUtil::fileExists(fullFilename)) {
91 
92  // Failure mode is on, so kill the current run.
93  if (m_fileExistsAction == eFail) {
94  log() << LOG::fatal << LOG::name << LOG::sep << "LCIO file already exists: " << fullFilename << LOG::done;
96  // Deletion mode is on, so try to remove the current file.
97  } else if (m_fileExistsAction == eDelete) {
98  if (FileUtil::removeFile(fullFilename) != 0) {
99  // Fatal error. File could not be removed.
100  log() << LOG::fatal << LOG::head << "Unable to delete old LCIO file: " << fullFilename << LOG::done;
102  } else {
103  log().okay("Deleted old LCIO file: " + fullFilename);
104  }
105  }
106  // Append mode is on.
107  else if (m_fileExistsAction == eAppend) {
108  log().okay("Appending to existing LCIO file: " + fullFilename);
109  writeMode = LCIO::WRITE_APPEND;
110  }
111  }
112  // Create a new file if doesn't exist.
113  else {
114  log().okay("Creating new LCIO file: " + fullFilename);
115  }
116 
117  // Open the file using the writer with the full path.
118  if (m_writer) {
119  if (!RunManager::instance()->isRunAborted()) {
120  m_writer->open(getFullOutputPath(false), writeMode);
121  m_writerIsOpen = true;
122  }
123  } else {
124  //G4Exception("", "", FatalException, "LCWriter is null.");
125  log() << LOG::fatal << LOG::head << "LCWriter is null." << LOG::done;
127  }
128 }
129 
131  string s = StringUtil::toLower(feaStr);
133  if (s == "fail") {
134  fea = eFail;
135  } else if (s == "overwrite" || s == "delete") {
136  fea = eDelete;
137  } else if (s == "append") {
138  fea = eAppend;
139  }
140 
141  return fea;
142 }
143 
144 void LcioManager::setRunNumber(int runNumber) {
145  m_runNumber = runNumber;
146  log().verbose("Set starting run number <" + StringUtil::toString((int)runNumber) + ">");
147 }
148 
150  m_writer = IOIMPL::LCFactory::getInstance()->createLCWriter();
151 }
152 
154  if (m_writer != 0) {
155  if (m_writerIsOpen) {
156  try {
157  m_writer->close();
158  m_writerIsOpen = false;
159  } catch (...) {
160  }
161  }
162  delete m_writer;
163  m_writer = 0;
164  }
165 }
166 
167 string LcioManager::getFullOutputPath(bool withExtension) {
168  string fullPath;
169 
170  if (m_path.length() > 0) {
171  // Append the output directory if one exists.
172  fullPath = m_path;
173  } else {
174  // Default to the current directory if none specified.
175  fullPath = ".";
176  }
177 
178  // Append file name.
179  fullPath += "/" + m_filename;
180 
181  // Append extension.
182  if (withExtension) {
183  fullPath += ".slcio";
184  }
185 
186  return fullPath;
187 }
188 
189 void LcioManager::beginRun(const G4Run* aRun) {
190 
191  // Set the G4Run counter.
192 #if ( G4VERSION_NUMBER >= 1000 )
193  G4RunManager::GetRunManager()->GetNonConstCurrentRun()->SetRunID(m_runNumber);
194 #else
195  // Alternate code for backward compatibility.
196  const_cast<G4Run *>(G4RunManager::GetRunManager()->GetCurrentRun())->SetRunID(m_runNumber);
197 #endif
198 
199  // Automatically create LCIO output file name if option was selected.
200  if (m_usingAutoname) {
201  makeAutoname();
202  }
203 
204  // Open the LCIO output file for writing.
205  openLcioFile();
206 
207  // Run aborted, because LCIO output file already exists.
208  if (!RunManager::instance()->isRunAborted()) {
209 
210  // create new LCRunHeader
211  createRunHeader(aRun);
212 
213  // write the run header
214  m_writer->writeRunHeader(m_runHdr);
215 
216  // Incr run number.
217  ++m_runNumber;
218  }
219 }
220 
221 void LcioManager::endRun(const G4Run*) {
222 
223  // Delete the LCIO run header object.
224  deleteRunHeader();
225 
226  // Set append mode for subsequent writes if interactive mode and the run was not aborted.
227  if (!RunManager::instance()->isRunAborted()) {
228  // If run was aborted, writer was never opened.
229  if (m_writer != 0) {
230  m_writer->close();
231  m_writerIsOpen = false;
232  }
233  // Close the writer to flush it (could be reopened).
236  }
237  }
238 }
239 
240 void LcioManager::createRunHeader(const G4Run*) {
241  // create new run header
242  m_runHdr = new LCRunHeaderImpl();
243 
244  // Write SLIC version into run header.
245  m_runHdr->parameters().setValue("SLIC_VERSION", PackageInfo::getVersion());
246 
247  // set run number
248  m_runHdr->setRunNumber(m_runNumber);
249 
250  // set detector name in LCIO header
251  setDetectorName();
252 
253  // add active subdet to header
255 }
256 
258  string det_tag = LCDDProcessor::instance()->getDetectorName();
259  m_runHdr->setDetectorName(det_tag);
260  log().okay("Detector name set to <" + det_tag + "> in run header.");
261 }
262 
264  if (m_runHdr) {
265  delete m_runHdr;
266  m_runHdr = 0;
267  }
268 }
269 
271  LCDDProcessor::SensitiveDetectors::const_iterator iter;
272  LCDDProcessor* lcddProc = LCDDProcessor::instance();
273 
274  for (iter = lcddProc->getSensitiveDetectorsBegin(); iter != lcddProc->getSensitiveDetectorsEnd(); iter++) {
275  m_runHdr->addActiveSubdetector((iter->second)->GetName());
276  }
277 }
278 
279 void LcioManager::setPath(const string& path) {
280  log().okay("Set output directory to <" + path + ">.");
281 
282  m_path = path;
283 }
284 
285 void LcioManager::setFilename(const string& filename) {
286  m_filename = filename;
287 
288  /* If the given filename has an extension, then remove it.
289  The LCIO library will add it automatically. */
290  size_t hasExt = filename.find(".slcio");
291  if (hasExt != string::npos) {
292  m_filename.replace(filename.size() - 6, 6, "");
293  }
294 
295  log().okay("Set output file name to <" + m_filename + ">.");
296 }
297 
298 void LcioManager::setAutonameFields(const std::vector<std::string>& fields) {
299  m_usingAutoname = true;
300  m_currentAutonameFields.clear();
301  for (std::vector<std::string>::const_iterator it = fields.begin(); it != fields.end(); it++) {
302  m_currentAutonameFields.push_back(*it);
303  }
304 }
305 
307  std::string autoname = m_namer->makeFileName(m_currentAutonameFields);
308  if (autoname.size() == 0 || autoname == "") {
309  log().warning("Autonaming returned an empty string. Using default file name <" + m_defaultFileName + ">");
311  } else {
312  setFilename(autoname);
313  log().okay("Autoname set file name to <" + autoname + ">.");
314  }
315 }
316 
317 LCEventImpl* LcioManager::createLCEvent(const G4Event *anEvent) {
318 
319  /* Create the LCEvent and set basic parameters. */
320  LCEventImpl* lcevt = new LCEventImpl();
321  lcevt->setEventNumber(anEvent->GetEventID());
322  lcevt->setRunNumber(m_runHdr->getRunNumber());
323  lcevt->setDetectorName(m_runHdr->getDetectorName());
324 
325  /* Get the current MCParticle collection. */
326  LCCollection* mcpColl = MCParticleManager::instance()->getMCParticleCollection();
327 
328  if (mcpColl != 0) {
329 
330  /* Set the event weight. */
331  float eventWeight = mcpColl->getParameters().getFloatVal("_weight");
332  if (eventWeight != 0.0) {
333  lcevt->setWeight(eventWeight);
334  }
335 
336  /* Set the idrup. */
337  int idrup = mcpColl->getParameters().getIntVal("_idrup");
338  //G4cout << "idrup = " << idrup << G4endl;
339  if (idrup != 0) {
340  lcevt->parameters().setValue("_idrup", idrup);
341  }
342  }
343 
344  // Write SLIC version into event header.
345  lcevt->parameters().setValue("SLIC_VERSION", PackageInfo::getVersion());
346 
347  /* Set the current LCEvent. */
348  setCurrentLCEvent(lcevt);
349 
350  return lcevt;
351 }
352 
354  return createLCEvent(G4EventManager::GetEventManager()->GetNonconstCurrentEvent());
355 }
356 
357 void LcioManager::endEvent(const G4Event*) {
358 
359  // create HC in current LCEvent from current G4Event using builder
361 
362  // Dump event stats.
363  if (m_enableDumpEvent) {
364  LCTOOLS::dumpEventDetailed(m_currentLCEvent);
365  }
366 
367  // set timestamp
369 
370  // write event
371  m_writer->writeEvent(m_currentLCEvent);
372 
373  // flush writer
374  m_writer->flush();
375 
376  // delete event's transient objects, including current LCEvent
377  delete m_currentLCEvent;
378  m_currentLCEvent = 0;
379 }
380 
382  getCurrentLCEvent()->setTimeStamp(TimeUtil::getTimeNS());
383 }
384 
386  m_HCBuilder->createHitCollectionsFromEvent(G4EventManager::GetEventManager()->GetNonconstCurrentEvent(), m_currentLCEvent);
387 }
388 
389 void LcioManager::addCollection(EVENT::LCEvent* event, EVENT::LCCollection* collection, const std::string &collectionName) {
390  event->addCollection(collection, collectionName);
391 }
392 
393 void LcioManager::addCollection(EVENT::LCCollection* collection, const std::string& collectionName) {
394  getCurrentLCEvent()->addCollection(collection, collectionName);
395 }
396 
397 } // namespace slic
static SlicApplication * instance()
static int removeFile(const char *filename)
Definition: FileUtil.cc:13
static bool fileExists(const char *filename)
Definition: FileUtil.cc:22
Automatically name LCIO output files according to input settings.
std::string makeFileName(std::vector< std::string > fields)
Builds Lcio hits collections from G4/SLIC event data.
EVENT::LCEvent * createHitCollectionsFromEvent(const G4Event *event, EVENT::LCEvent *lcioEvent)
Singleton manager class of LCIO configuration and output file operations.
Definition: LcioManager.hh:45
std::vector< std::string > m_currentAutonameFields
Definition: LcioManager.hh:320
IO::LCWriter * m_writer
Definition: LcioManager.hh:289
void endRun(const G4Run *run)
Definition: LcioManager.cc:221
void setCurrentLCEvent(IMPL::LCEventImpl *anLCEvent)
Definition: LcioManager.hh:159
LcioFileNamer * m_namer
Definition: LcioManager.hh:317
LcioHitsCollectionBuilder * m_HCBuilder
Definition: LcioManager.hh:303
std::string getFullOutputPath(bool withExtension=false)
Definition: LcioManager.cc:167
void setRunNumber(int runNumber)
Definition: LcioManager.cc:144
void createHitsCollections()
Definition: LcioManager.cc:385
static EFileExistsAction getFileExistsActionFromString(const std::string &fileExists)
Definition: LcioManager.cc:130
void setFilename(const std::string &filename)
Definition: LcioManager.cc:285
LcioMessenger * m_messenger
Definition: LcioManager.hh:309
void addActiveSubdetectors()
Definition: LcioManager.cc:270
std::string m_path
Definition: LcioManager.hh:297
void setEventTimeStamp()
Definition: LcioManager.cc:381
void setAutonameFields(const std::vector< std::string > &fields)
Definition: LcioManager.cc:298
IMPL::LCEventImpl * getCurrentLCEvent()
Definition: LcioManager.hh:167
void setPath(const std::string &path)
Definition: LcioManager.cc:279
void endEvent(const G4Event *anEvent)
Definition: LcioManager.cc:357
virtual ~LcioManager()
Definition: LcioManager.cc:72
void beginRun(const G4Run *run)
Definition: LcioManager.cc:189
static std::string m_defaultFileName
Definition: LcioManager.hh:319
std::string m_filename
Definition: LcioManager.hh:295
IMPL::LCEventImpl * m_currentLCEvent
Definition: LcioManager.hh:306
void addCollection(EVENT::LCEvent *lcevent, EVENT::LCCollection *collection, const std::string &name)
Definition: LcioManager.cc:389
EFileExistsAction m_fileExistsAction
Definition: LcioManager.hh:312
IMPL::LCEventImpl * createLCEvent()
Definition: LcioManager.cc:353
void createRunHeader(const G4Run *run)
Definition: LcioManager.cc:240
IMPL::LCRunHeaderImpl * m_runHdr
Definition: LcioManager.hh:292
G4UIcommand class for LCIO commands.
LogStream & verbose()
Definition: LogStream.hh:238
LogStream & okay()
Definition: LogStream.hh:246
LogStream & warning()
Definition: LogStream.hh:254
Base class for slic code modules that provides common functionality, such as logging to an output str...
Definition: Module.hh:25
LogStream & log()
Definition: Module.hh:99
static RunManager * instance()
Definition: RunManager.hh:38
static long64 getTimeNS()
Definition: TimeUtil.hh:31
@ fatal
Definition: LogStream.hh:33
@ head
Definition: LogStream.hh:26
@ name
Definition: LogStream.hh:26
@ done
Definition: LogStream.hh:26
@ sep
Definition: LogStream.hh:26