00001 #include "Gnrtr.h"
00002 #include "GenTools/IHepMCEventMutator.h"
00003
00004 #include "Event/GenHeader.h"
00005
00006 #include "Context/TimeStamp.h"
00007
00008 #include "GaudiKernel/ISvcLocator.h"
00009 #include "GaudiKernel/IDataProviderSvc.h"
00010 #include "GaudiKernel/IDataManagerSvc.h"
00011 #include "GaudiKernel/IRndmEngine.h"
00012
00013 #include "GaudiKernel/IssueSeverity.h"
00014
00015 #include "HepMC/GenEvent.h"
00016
00017 #include <vector>
00018 #include "CLHEP/Units/SystemOfUnits.h"
00019 #include <limits>
00020
00021 Gnrtr::Gnrtr(const std::string& name, ISvcLocator* pSvcLocator)
00022 : StageProcessor<DayaBay::GenHeader>(name,pSvcLocator)
00023 {
00024 declareProperty("TimeStamp",m_tsseconds = 0,
00025 "Absolute start time in seconds from the unix epoch. "
00026 "Caution: this is a bare integer, do not multiply by CLHEP seconds.");
00027
00028 declareProperty("TimeStampNano",m_tsnanoseconds = 0,
00029 "Time offset in nanoseconds to add to the absolute start time");
00030
00031 m_pullMode=true;
00032
00033 GT_constructor();
00034 }
00035
00036 Gnrtr::~Gnrtr()
00037 {
00038 GT_destructor();
00039 }
00040
00041 StatusCode Gnrtr::initialize()
00042 {
00043 StatusCode sc = this->StageProcessor<DayaBay::GenHeader>::initialize();
00044 if (sc.isFailure()) return sc;
00045
00046 m_Start=true;
00047
00048
00049 m_CurrentTime=0;
00050
00051 m_now = TimeStamp(m_tsseconds,m_tsnanoseconds);
00052
00053 return GT_initialize();
00054 }
00055
00056 StatusCode Gnrtr::execute()
00057 {
00059 if(m_Start || m_CurrentTime <= thisStage()->currentTime()) {
00060 m_Start=false;
00061 GnrtrData* pGD=0;
00062
00063
00064
00065 preExecute();
00066 StatusCode sc = GT_execute(pGD);
00067 if(sc.isFailure()) {
00068 return sc;
00069 }
00070 postExecute();
00071
00072 thisStage()->pushElement(pGD);
00073 this->registerData(*pGD);
00074 m_CurrentTime=pGD->time();
00075 debug()<<"to grep: new data pushed out at time "<<pGD->time()<<endreq;
00076 }
00077
00078 return StatusCode::SUCCESS;
00079 }
00080
00081 StatusCode Gnrtr::finalize()
00082 {
00083 return GT_finalize();
00084 }
00085
00090
00091 void Gnrtr::GT_constructor()
00092 {
00093 declareProperty("GenTools",m_genToolNames,
00094 "Tools to generate HepMC::GenEvents");
00095 declareProperty("GenName", m_genName = "GtGenerator",
00096 "Name of this generator for book keeping purposes.");
00097 }
00098
00099
00100 void Gnrtr::GT_destructor()
00101 {
00102 }
00103
00104 StatusCode Gnrtr::GT_initialize()
00105 {
00106 for (size_t ind=0; ind < m_genToolNames.size(); ++ind) {
00107 std::string gtn = m_genToolNames[ind];
00108 try {
00109 m_genTools.push_back(tool<IHepMCEventMutator>(gtn));
00110 }
00111 catch(const GaudiException& exg) {
00112 fatal() << "Failed to get generator: \"" << gtn << "\"" << endreq;
00113 return StatusCode::FAILURE;
00114 }
00115 info () << "Added gen tool " << gtn << endreq;
00116 }
00117
00118 return StatusCode::SUCCESS;
00119 }
00120
00121 StatusCode Gnrtr::GT_execute(GnrtrData*& p_output)
00122 {
00123
00124 DayaBay::GenHeader* gen_header = MakeHeaderObject();
00125
00126
00127 HepMC::GenEvent* event = new HepMC::GenEvent;
00128 event->set_event_number(this->getExecNum());
00129
00130
00131 for (size_t ind = 0; ind< m_genTools.size(); ++ind) {
00132 debug () << "Running gen tool #" << ind << " " << m_genToolNames[ind]
00133 << endreq;
00134 if (m_genTools[ind]->mutate(*event).isFailure()) {
00135 fatal() << "Generator Tool " << m_genToolNames[ind]
00136 << " failed" << endreq;
00137 return StatusCode::FAILURE;
00138 }
00139 }
00140
00141
00142 double dt = std::numeric_limits<double>::max();
00143 {
00144 HepMC::GenEvent::vertex_const_iterator it, done = event->vertices_end();
00145 for (it = event->vertices_begin(); it != done; ++it) {
00146 double t = (*it)->position().t();
00147 debug()<<"time of this vertex: "<<t<<endreq;
00148 if (t < dt) dt = t;
00149 }
00150 }
00151 debug () << "Smallest time of "
00152 << event->vertices_size() << " vertices = " << dt << endreq;
00153
00154
00155 dt = dt/CLHEP::second;
00156 time_t seconds = (time_t)dt;
00157 double fractional = dt - seconds;
00158 int ns = (int)(1e9*fractional);
00159 double rest = fractional - (1e-9*ns);
00160
00161
00162 double toffset = (dt - rest)*CLHEP::second;
00163
00164
00165 m_now.Add(TimeStamp(seconds,ns));
00166 gen_header->setTimeStamp(m_now);
00167
00168 debug() << "Offset time is " << toffset
00169 << ", now is " << m_now << endreq;
00170
00171
00172
00173 {
00174 double earliest = -1, latest = -1;
00175 HepMC::GenEvent::vertex_iterator it, done = event->vertices_end();
00176 for (it = event->vertices_begin(); it != done; ++it) {
00177 HepMC::FourVector vtx = (*it)->position();
00178 double t = vtx.t() - toffset;
00179 vtx.setT(t);
00180 (*it)->set_position(vtx);
00181
00182 if (earliest < 0 || earliest > t) earliest = t;
00183 if (latest < 0 || latest < t) latest = t;
00184 }
00185
00186 TimeStamp ts_earliest(m_now);
00187 if (earliest > 0)
00188 ts_earliest.Add(earliest/CLHEP::second);
00189 gen_header->setEarliest(ts_earliest);
00190
00191 TimeStamp ts_latest(m_now);
00192 if (latest > 0)
00193 ts_latest.Add(latest/CLHEP::second);
00194 gen_header->setLatest(ts_latest);
00195 }
00196
00197
00198 gen_header->setEvent(event);
00199 gen_header->setGeneratorName(m_genName);
00200
00201
00205 p_output=new GnrtrData(*gen_header);
00206
00207
00208 return StatusCode::SUCCESS;
00209
00210 }
00211
00212 StatusCode Gnrtr::GT_finalize()
00213 {
00214 for (size_t ind=0; ind < m_genTools.size(); ++ind)
00215 m_genTools[ind]->release();
00216 m_genTools.clear();
00217
00218 return this->StageProcessor<DayaBay::GenHeader>::finalize();
00219 }
00220
00221
00222
00223
00224