00001 #include "DigitizeAlg/DigitizeAlg.h"
00002
00003 #include "Event/ElecHeader.h"
00004 #include "Event/ElecFeeCrate.h"
00005 #include "Event/ElecFecCrate.h"
00006 #include "Event/RegistrationSequence.h"
00007
00008 #include "ElecSim/IEsPulseTool.h"
00009 #include "ElecSim/IEsFrontEndTool.h"
00010 #include "Conventions/Electronics.h"
00011
00012 #include "SimHitSplitSvc/SimHitSplitSvc.h"
00013 #include "Event/SimReadoutHeader.h"
00014
00015 #include <map>
00016 #include <algorithm>
00017
00018 using namespace DayaBay;
00019
00020 DigitizeAlg::DigitizeAlg(const string& name, ISvcLocator* pSvcLocator)
00021 :DybAlgorithm<SimReadoutHeader>(name,pSvcLocator)
00022 , m_pmtTool(0)
00023 , m_rpcTool(0)
00024 , m_feeTool(0)
00025 , m_fecTool(0)
00026 , m_triggerSorter(0)
00027 , m_roTrigPackTool(0)
00028 , m_simHitSplitSvc(0)
00029 {
00030
00031
00032
00033
00034
00035 declareProperty("Detectors",m_detectorNames,"List of active detectors");
00036 declareProperty("PmtTool",m_pmtToolName="EsPmtEffectPulseTool",
00037 "Name of the PMT simulation tool");
00038 declareProperty("RpcTool",m_rpcToolName="EsIdealPulseTool",
00039 "Name of the RPC simulation tool");
00040 declareProperty("FeeTool",m_feeToolName="EsIdealFeeTool",
00041 "Name of the PMT Front-end electronics simulation tool");
00042 declareProperty("FecTool",m_fecToolName="EsIdealFecTool",
00043 "Name of the RPC Front-end electronics simulation tool");
00044
00045
00046 m_detectorNames.push_back("DayaBayAD1");
00047 m_detectorNames.push_back("DayaBayAD2");
00048 m_detectorNames.push_back("DayaBayIWS");
00049 m_detectorNames.push_back("DayaBayOWS");
00050
00051 m_detectorNames.push_back("LingAoAD1");
00052 m_detectorNames.push_back("LingAoAD2");
00053 m_detectorNames.push_back("LingAoIWS");
00054 m_detectorNames.push_back("LingAoOWS");
00055
00056 m_detectorNames.push_back("FarAD1");
00057 m_detectorNames.push_back("FarAD2");
00058 m_detectorNames.push_back("FarAD3");
00059 m_detectorNames.push_back("FarAD4");
00060 m_detectorNames.push_back("FarIWS");
00061 m_detectorNames.push_back("FarOWS");
00062
00063
00064
00065 m_trigToolNames.push_back("TsMultTriggerTool");
00066 declareProperty("TrigTools", m_trigToolNames, "Tools to generate Triggers");
00067 declareProperty("TriggerFilter", m_trigFilterName = "TsSortTool",
00068 "Tool to do final filtering/combining of triggers");
00069
00070
00071 m_roToolNames.push_back("ROsFeeReadoutTool");
00072 m_roToolNames.push_back("ROsFecReadoutTool");
00073 declareProperty("RoTools", m_roToolNames, "Tools to generate Triggers");
00074 declareProperty("TrigPackagerTool", m_roTrigPackName = "ROsTriggerDataPackerTool",
00075 "Tool to convert trigger commands from TrigSim to TriggerDataPackage");
00076 }
00077
00078 DigitizeAlg::~DigitizeAlg()
00079 {
00080 }
00081
00082 StatusCode DigitizeAlg::initialize()
00083 {
00084
00085
00086 for(vector<string>::size_type detIdx = 0; detIdx < m_detectorNames.size(); detIdx++)
00087 {
00088 Detector det(m_detectorNames[detIdx]);
00089 if(det.site() == Site::kUnknown || det.detectorId() == DetectorId::kUnknown)
00090 {
00091 error()<< "Invalid detector name: "<< m_detectorNames[detIdx]<< endreq;
00092 return StatusCode::FAILURE;
00093 }
00094 m_detectors.push_back(det);
00095 }
00096
00097 StatusCode sc = this->GaudiAlgorithm::initialize();
00098 if(sc.isFailure())
00099 {
00100 error()<< "Error when initializing GaudiAlgorithm."<< endreq;
00101 return sc;
00102 }
00103
00104 debug()<< "DigitizeAlg ininalize()"<< endreq;
00105
00106
00107 IService* isvc = 0;
00108 sc = serviceLocator()->service("SimHitSplitSvc", isvc, false);
00109 if(sc.isFailure())
00110 {
00111 error()<< "Service : SimHitSplitSvc could not be retrieved!"<< endreq;
00112 return sc;
00113 }
00114 isvc->addRef();
00115 sc = isvc->queryInterface(ISimHitSplitSvc::interfaceID(), (void**)&m_simHitSplitSvc);
00116 if(sc.isFailure())
00117 {
00118 error()<< "SimHitSplitSvc does not implement ISimHitSplitSvc"<< endreq;
00119 return sc;
00120 }
00121
00122
00123 try
00124 {
00125 m_pmtTool = tool<IEsPulseTool>(m_pmtToolName);
00126 }
00127 catch(const GaudiException& exg)
00128 {
00129 fatal()<< "Failed to get pmt tool: \""<< m_pmtToolName<< "\""<< endreq;
00130 return StatusCode::FAILURE;
00131 }
00132 debug()<< "Added tool "<< m_pmtToolName<< endreq;
00133
00134
00135 if(m_pmtToolName == m_rpcToolName)
00136 {
00137 m_rpcTool = m_pmtTool;
00138 }
00139 else
00140 {
00141 try
00142 {
00143 m_rpcTool = tool<IEsPulseTool>(m_rpcToolName);
00144 }
00145 catch(const GaudiException& exg)
00146 {
00147 fatal()<< "Failed to get rpc tool: \""<< m_rpcToolName<< "\""<< endreq;
00148 return StatusCode::FAILURE;
00149 }
00150 debug()<< "Added tool "<< m_rpcToolName<< endreq;
00151 }
00152
00153
00154 try
00155 {
00156 m_feeTool = tool<IEsFrontEndTool>(m_feeToolName);
00157 }
00158 catch(const GaudiException& exg)
00159 {
00160 fatal()<< "Failed to get fee tool: \""<< m_feeToolName<< "\""<< endreq;
00161 return StatusCode::FAILURE;
00162 }
00163 debug()<< "Added tool "<< m_feeToolName<< endreq;
00164
00165
00166 try
00167 {
00168 m_fecTool = tool<IEsFrontEndTool>(m_fecToolName);
00169 }
00170 catch(const GaudiException& exg)
00171 {
00172 fatal()<< "Failed to get fec tool: \""<< m_fecToolName<< "\""<< endreq;
00173 return StatusCode::FAILURE;
00174 }
00175 debug()<< "Added tool "<< m_fecToolName<< endreq;
00176
00177
00178 for(vector<string>::size_type ind = 0; ind < m_trigToolNames.size(); ind++)
00179 {
00180 string tgr = m_trigToolNames[ind];
00181 try
00182 {
00183 m_trigTools.push_back(tool<ITsTriggerTool>(tgr));
00184 }
00185 catch(const GaudiException& exg)
00186 {
00187 fatal()<< "Failed to get Trigger Tool: \""<< tgr<< "\""<< endreq;
00188 return StatusCode::FAILURE;
00189 }
00190 debug()<< "Added trigger tool "<< tgr<< endreq;
00191 }
00192 try
00193 {
00194 m_triggerSorter = tool<ITsTriggerTool>(m_trigFilterName);
00195 }
00196 catch(const GaudiException& exg)
00197 {
00198 fatal()<< "Failed to get TriggerFilterTool: \""<< m_trigFilterName<< "\""<< endreq;
00199 return StatusCode::FAILURE;
00200 }
00201
00202
00203 try
00204 {
00205 m_roTrigPackTool = tool<IROsTriggerDataPackerTool>(m_roTrigPackName);
00206 }
00207 catch(const GaudiException& exg)
00208 {
00209 fatal()<< "Failed to get Readout Trigger Package Tool: \""
00210 << m_roTrigPackName<< "\""<< endreq;
00211 return StatusCode::FAILURE;
00212 }
00213
00214 for(vector<string>::size_type ind = 0; ind < m_roToolNames.size(); ind++)
00215 {
00216 string rotool = m_roToolNames[ind];
00217 try
00218 {
00219 m_roTools.push_back(tool<IROsReadoutTool>(rotool));
00220 }
00221 catch(const GaudiException& exg)
00222 {
00223 fatal()<< "Failed to get Readout Tool: \""<< rotool<< "\""<< endreq;
00224 return StatusCode::FAILURE;
00225 }
00226 debug()<< "Added readout tool "<< rotool<< endreq;
00227 }
00228
00229 return sc;
00230 }
00231
00232 StatusCode DigitizeAlg::execute()
00233 {
00234 debug()<< "Digitalization execute()...."<< endreq;
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256 debug()<< "Now get SimHitHeaders!"<< endreq;
00257
00258 DayaBay::SimHeader* sh = getTES<SimHeader>(SimHeaderLocation::Default);
00259 vector<SimHitHeader*> shhs;
00260
00261
00262 SimReadoutHeader* simReadoutHeader = MakeHeaderObject();
00263 simReadoutHeader->setContext(sh->context());
00264 SimReadoutHeader::SimReadoutContainer &readouts = simReadoutHeader->readouts();
00265
00266
00267 TimeStamp earliest(sh->earliest());
00268 TimeStamp latest(sh->latest());
00269 TimeStamp timeStamp(sh->timeStamp());
00270
00271 StatusCode sc = m_simHitSplitSvc->getSimHitHeader(sh, shhs, m_hitEarliest, m_hitLatest);
00272 if(sc.isFailure()) return sc;
00273
00274 debug()<< "Number of SimHits segments: "<< shhs.size()<< endreq;
00275
00276 for(vector<SimHitHeader*>::size_type i = 0; i < shhs.size(); i++)
00277 {
00278
00279 debug()<< "Now get one ElecHeader!"<< endreq;
00280 ElecHeader* eh = new ElecHeader();
00281 debug()<< "ElecHeader at "<< eh<< "\n"
00282 << "Electronics simulation...."<< endreq;
00283 StatusCode sc = this->ElecSim(shhs[i], i, eh);
00284 if(sc.isFailure())
00285 {
00286 error()<< "Error in ElecSim():"<< endreq;
00287 return sc;
00288 }
00289
00290
00291
00292
00293 debug()<< "Now get one SimReadout....."<< endreq;
00294 SimReadoutHeader* srh = new SimReadoutHeader();
00295 debug()<< "SimReadoutHeader at "<< srh<< "\n"
00296 << "SimReadout simulation...."<< endreq;
00297 sc = this->TrigExecute(eh, srh);
00298 if(sc.isFailure())
00299 {
00300 error()<< "Error in TrigExecute():"<< endreq;
00301 return sc;
00302 }
00303 delete eh;
00304
00305 if(0 == i)
00306 {
00307 earliest = srh->earliest();
00308 timeStamp = srh->timeStamp();
00309 }
00310 if(i == (shhs.size() - 1)) latest = srh->latest();
00311
00312 SimReadoutHeader::SimReadoutContainer &src = srh->readouts();
00313 for(unsigned j = 0; j < src.size(); j++)
00314 {
00315 src[j]->setHeader(simReadoutHeader);
00316 readouts.push_back(src[j]);
00317 }
00318
00319 srh->readouts().clear();
00320 delete srh;
00321 }
00322
00323 if(shhs.size() != 1 || shhs[0] != sh->hits())
00324 {
00325 for(vector<SimHitHeader*>::size_type i = 0; i < shhs.size(); i++)
00326 {
00327 SimHitHeader::hc_map& maphc = shhs[i]->hitCollection();
00328 for(SimHitHeader::hc_map::iterator it = maphc.begin(); it != maphc.end(); ++it)
00329 {
00330 it->second->collection().clear();
00331 }
00332 delete shhs[i];
00333 }
00334 }
00335
00336 simReadoutHeader->setEarliest(earliest);
00337 simReadoutHeader->setLatest(latest);
00338 simReadoutHeader->setTimeStamp(timeStamp);
00339
00340 m_hitEarliest.clear();
00341 m_hitLatest.clear();
00342
00343 return StatusCode::SUCCESS;
00344 }
00345
00346
00347 StatusCode DigitizeAlg::ElecSim(const SimHitHeader* shh, int index, ElecHeader*& eh)
00348 {
00349
00350 debug()<< "Before setContext(): "<< eh->timeStamp().GetSec()
00351 << "--"<< eh->timeStamp().GetNanoSec()<< endreq;
00352
00353 m_hitEarliest[index].Add(-preTimeTolerance/CLHEP::second);
00354 m_hitLatest[index].Add(postTimeTolerance/CLHEP::second);
00355
00356 eh->setEarliest(m_hitEarliest[index]);
00357 eh->setLatest(m_hitLatest[index]);
00358 eh->setTimeStamp(m_hitEarliest[index]);
00359
00360 debug()<< "After setContext(): TimeStamp: "<< eh->timeStamp().GetSec()
00361 << "--"<< eh->timeStamp().GetNanoSec()<< endreq;
00362 debug()<< "After setContext(): Earliest: "<< eh->earliest().GetSec()
00363 << "--"<< eh->earliest().GetNanoSec()<< endreq;
00364 debug()<< "After setContext(): Latest: "<< eh->latest().GetSec()
00365 << "--"<< eh->latest().GetNanoSec()<< endreq;
00366
00367
00368 ElecPulseHeader* eph = new ElecPulseHeader(eh);
00369 eh->setPulseHeader(eph);
00370
00371
00372 ElecCrateHeader* ech = new ElecCrateHeader(eh);
00373 eh->setCrateHeader(ech);
00374
00375
00376
00377 map<short int, SimHitCollection*> mshc = shh->hitCollection();
00378
00379 debug()<< "Processing SimHit collections: "<< mshc.size()<< endreq;
00380
00381
00382 map<short int, SimHitCollection*>::iterator mit;
00383 for(mit = mshc.begin(); mit != mshc.end(); mit++)
00384 {
00385 Detector det(mit->first);
00386 debug()<< "Checking "<< det.detName()<< " for hits."<< endreq;
00387 SimHitCollection* hits = mit->second;
00388 if(!hits) return StatusCode::FAILURE;
00389
00390 if(det.isAD())
00391 {
00392 const vector<SimHit*> simhits = hits->collection();
00393 debug()<< "There are "<< simhits.size()<< " ADPMTSimHits"<< endreq;
00394
00395
00396
00397
00398
00399
00400 }
00401 else if(det.isWaterShield())
00402 {
00403 const vector<SimHit*> simhits = hits->collection();
00404 debug()<< "There are "<< simhits.size()<< " WSPMTSimHits"<< endreq;
00405
00406
00407
00408
00409
00410
00411 }
00412
00413 debug()<< "Get hit collection from "<< det.detName()<< " (id = "
00414 << det.siteDetPackedData()<< ") "<< " with "
00415 << hits->collection().size()<< " hits."<< endreq;
00416
00417 StatusCode sc;
00418
00419 if(find(m_detectors.begin(), m_detectors.end(), det) == m_detectors.end())
00420 {
00421 debug()<< "Detector "<< det.detName()<< " need not to be simulated."<< endreq;
00422 continue;
00423 }
00424 if(det.isAD() || det.isWaterShield())
00425 {
00426
00427 debug()<< "Processing PMT hits."<< endreq;
00428 ElecPulseCollection* pulses = new ElecPulseCollection(eph, det);
00429 sc = m_pmtTool->generatePulses(hits, pulses);
00430 if(sc != StatusCode::SUCCESS) return sc;
00431 eph->addPulseCollection(pulses);
00432
00433 ElecFeeCrate* crate = new ElecFeeCrate(det, ech);
00434 debug()<< "Before generateSignals: Crate: "<< crate<< endreq;
00435 sc = m_feeTool->generateSignals(pulses, crate);
00436
00437 if(sc != StatusCode::SUCCESS) return sc;
00438
00439 ech->addCrate(crate);
00440 }
00441 else if(det.detectorId() == DetectorId::kRPC)
00442 {
00443
00444 debug()<< "Processing RPC hits."<< endreq;
00445 ElecPulseCollection* pulses = new ElecPulseCollection(eph, det);
00446 sc = m_rpcTool->generatePulses(hits, pulses);
00447 if(sc != StatusCode::SUCCESS) return sc;
00448 eph->addPulseCollection(pulses);
00449
00450 ElecFecCrate* crate = new ElecFecCrate(det, ech);
00451 sc = m_fecTool->generateSignals(pulses, crate);
00452 if(sc != StatusCode::SUCCESS) return sc;
00453 ech->addCrate(crate);
00454 }
00455 else
00456 {
00457 error()<< "Unknown detector "<< det<< endreq;
00458 return StatusCode::FAILURE;
00459 }
00460 }
00461
00462 debug()<< "To grep: (Full Elec) new data pushed out at time "<< m_hitEarliest<< endreq;
00463
00464 return StatusCode::SUCCESS;
00465 }
00466
00467 StatusCode DigitizeAlg::TrigSim(const ElecHeader& eh, SimTrigHeader*& th)
00468 {
00469 th->setCommandHeader(new SimTrigCommandHeader(th));
00470
00471
00472 th->setContext(eh.context());
00473 th->setTimeStamp(eh.timeStamp());
00474 th->setEarliest(eh.earliest());
00475 th->setLatest(eh.latest());
00476
00477 debug()<< "TrigSim time: "<< endreq;
00478 debug()<< "Earliest: "<< th->earliest().GetSec()<< "--"<< th->earliest().GetNanoSec()<< " "
00479 << "Latest: "<< th->latest().GetSec()<< "--"<< th->latest().GetNanoSec()<< endreq;
00480
00481
00482 for(vector<ITsTriggerTool*>::size_type ind = 0; ind < m_trigTools.size(); ind++)
00483 {
00484 debug()<< "Running trigger tool #"<< ind<< " "<< m_trigToolNames[ind]<< endreq;
00485
00486 StatusCode sc = m_trigTools[ind]->mutate(th, eh);
00487 if(sc.isFailure())
00488 {
00489 fatal()<< "Trigger Tool "<< m_trigToolNames[ind]<< " failed"<< endreq;
00490 delete th;
00491 th = 0;
00492 return StatusCode::FAILURE;
00493 }
00494 }
00495 if(m_triggerSorter->mutate(th, eh).isFailure())
00496 {
00497 fatal()<< "Trigger Tool "<< m_trigFilterName<< " "<< m_triggerSorter<< " failed"<< endreq;
00498 return StatusCode::FAILURE;
00499 }
00500
00501 return StatusCode::SUCCESS;
00502 }
00503
00504 StatusCode DigitizeAlg::ReadoutSim(const ElecHeader& eh, const SimTrigHeader& th, SimReadoutHeader*& srh)
00505 {
00506 srh->setContext(eh.context());
00507 srh->setTimeStamp(eh.timeStamp());
00508 srh->setEarliest(eh.earliest());
00509 srh->setLatest(eh.latest());
00510
00511 debug()<< "ReadoutSim time: "<< endreq;
00512 debug()<< srh->earliest().GetSec()<< "--"<< srh->earliest().GetNanoSec()<< " "
00513 << srh->latest().GetSec()<< "--"<< srh->latest().GetNanoSec()<< endreq;
00514
00515
00516
00517
00518 debug()<< "Creating Trigger Data Packages."<< endreq;
00519
00520 vector<ReadoutTriggerDataPkg*> trigPkgs;
00521
00522 StatusCode sc = m_roTrigPackTool->fillDataPakages(trigPkgs, th);
00523 if(sc.isFailure())
00524 {
00525 fatal()<< "Readout Tool "<< m_roTrigPackName<< " "<< m_roTrigPackTool<< " failed"<< endreq;
00526 return StatusCode::FAILURE;
00527 }
00528
00529
00530 for(vector<IROsReadoutTool*>::size_type ind = 0; ind < m_roTools.size(); ++ind)
00531 {
00532 debug()<< "Running readout tool #"<< ind<< " "<< m_roToolNames[ind]<< endreq;
00533
00534 sc = m_roTools[ind]->mutate(srh, trigPkgs, eh);
00535 if(sc.isFailure())
00536 {
00537 fatal()<< "Readout Tool "<< m_roToolNames[ind]<< " failed"<< endreq;
00538 delete srh;
00539 srh = 0;
00540 return StatusCode::FAILURE;
00541 }
00542 }
00543
00544 return StatusCode::SUCCESS;
00545 }
00546
00547 StatusCode DigitizeAlg::TrigExecute(const ElecHeader* eh, SimReadoutHeader*& srh)
00548 {
00549 debug()<< "Running Trigger and Readout Simulation!"<< endreq;
00550
00551 const ElecPulseHeader::PulseCollectionMap& pcmap = eh->pulseHeader()->pulseCollection();
00552 debug()<< "TrigExecute() get "<< pcmap.size()<< " pulse collections:"<< endreq;
00553 ElecPulseHeader::PulseCollectionMap::const_iterator it, done = pcmap.end();
00554 for(it = pcmap.begin(); it != done; ++it)
00555 {
00556 debug()<< "detector: "<< it->first<< " has "<< it->second->pulses().size()<< endreq;
00557 }
00558
00559 SimTrigHeader* th = new SimTrigHeader();
00560 StatusCode sc = this->TrigSim(*eh, th);
00561 if(sc.isFailure() || !th)
00562 {
00563 error()<< "TrigExecute(): Failed to run TrigSim!"<< endreq;
00564 return StatusCode::FAILURE;
00565 }
00566
00567
00568
00569
00570
00571
00572
00573 th->setExecNumber(srh->execNumber());
00574
00575 debug()<< "exec num "<< srh->execNumber()<< endreq;
00576
00577 sc = this->ReadoutSim(*eh, *th, srh);
00578 if(sc.isFailure() || !srh)
00579 {
00580 error()<< "TrigExecute(): Failed to run ReadoutSim"<< endreq;
00581 return StatusCode::FAILURE;
00582 }
00583
00584
00585 delete th;
00586
00587 return StatusCode::SUCCESS;
00588 }
00589
00590 StatusCode DigitizeAlg::finalize()
00591 {
00592 debug()<< "DigitizeAlg::finalize()...."<< endreq;
00593 this->DybAlgorithm<SimReadoutHeader>::finalize();
00594 return StatusCode::SUCCESS;
00595 }