00001 #include "DigitalizeAlg/DigitalizeAlg.h"
00002
00003 #include "Event/ElecHeader.h"
00004 #include "Event/ElecFeeCrate.h"
00005 #include "Event/ElecFecCrate.h"
00006
00007 #include "ElecSim/IEsPulseTool.h"
00008 #include "ElecSim/IEsFrontEndTool.h"
00009 #include "Conventions/Electronics.h"
00010
00011 #include "ROBufferSvc/ROBufferSvc.h"
00012 #include "PreElecSimSvc/PreElecSimSvc.h"
00013
00014 #include <map>
00015 #include <algorithm>
00016
00017 using namespace DayaBay;
00018
00019 DigitalizeAlg::DigitalizeAlg(const string& name, ISvcLocator* pSvcLocator)
00020 :DybAlgorithm<SimReadoutHeader>(name,pSvcLocator)
00021 , m_pmtTool(0)
00022 , m_rpcTool(0)
00023 , m_feeTool(0)
00024 , m_fecTool(0)
00025 , m_triggerSorter(0)
00026 , m_roTrigPackTool(0)
00027 , m_roBufferSvc(0)
00028 , m_preElecSimSvc(0)
00029 {
00030
00031 TimeStamp initime(0.0);
00032 m_hitEarliest = initime;
00033 m_hitLatest = initime;
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 m_detectorNames.push_back("DayaBayRPC");
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 m_detectorNames.push_back("LingAoRPC");
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 m_detectorNames.push_back("FarRPC");
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 DigitalizeAlg::~DigitalizeAlg()
00079 {
00080 }
00081
00082 StatusCode DigitalizeAlg::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 info()<< "DigitalizeAlg ininalize()"<< endreq;
00105
00106
00107 IService* isvc = 0;
00108 sc = serviceLocator()->service("PreElecSimSvc", isvc, false);
00109 if(sc.isFailure())
00110 {
00111 error()<< "Service : PreElecSimSvc could not be retrieved!"<< endreq;
00112 return sc;
00113 }
00114 isvc->addRef();
00115 sc = isvc->queryInterface(IPreElecSimSvc::interfaceID(), (void**)&m_preElecSimSvc);
00116 if(sc.isFailure())
00117 {
00118 error()<< "PreElecSimSvc does not implement IPreElecSimSvc"<< endreq;
00119 return sc;
00120 }
00121
00122
00123 isvc = 0;
00124 sc = serviceLocator()->service("ROBufferSvc", isvc, false);
00125 if(sc.isFailure())
00126 {
00127 error()<< "Service : ROBufferSvc could not be retrieved!"<< endreq;
00128 return sc;
00129 }
00130 isvc->addRef();
00131 sc = isvc->queryInterface(IROBufferSvc::interfaceID(), (void**)&m_roBufferSvc);
00132 if(sc.isFailure())
00133 {
00134 error()<< "ROBufferSvc does not implement IROBufferSvc"<< endreq;
00135 }
00136
00137
00138 try
00139 {
00140 m_pmtTool = tool<IEsPulseTool>(m_pmtToolName);
00141 }
00142 catch(const GaudiException& exg)
00143 {
00144 fatal()<< "Failed to get pmt tool: \""<< m_pmtToolName<< "\""<< endreq;
00145 return StatusCode::FAILURE;
00146 }
00147 info()<< "Added tool "<< m_pmtToolName<< endreq;
00148
00149
00150 if(m_pmtToolName == m_rpcToolName)
00151 {
00152 m_rpcTool = m_pmtTool;
00153 }
00154 else
00155 {
00156 try
00157 {
00158 m_rpcTool = tool<IEsPulseTool>(m_rpcToolName);
00159 }
00160 catch(const GaudiException& exg)
00161 {
00162 fatal()<< "Failed to get rpc tool: \""<< m_rpcToolName<< "\""<< endreq;
00163 return StatusCode::FAILURE;
00164 }
00165 info()<< "Added tool "<< m_rpcToolName<< endreq;
00166 }
00167
00168
00169 try
00170 {
00171 m_feeTool = tool<IEsFrontEndTool>(m_feeToolName);
00172 }
00173 catch(const GaudiException& exg)
00174 {
00175 fatal()<< "Failed to get fee tool: \""<< m_feeToolName<< "\""<< endreq;
00176 return StatusCode::FAILURE;
00177 }
00178 info()<< "Added tool "<< m_feeToolName<< endreq;
00179
00180
00181 try
00182 {
00183 m_fecTool = tool<IEsFrontEndTool>(m_fecToolName);
00184 }
00185 catch(const GaudiException& exg)
00186 {
00187 fatal()<< "Failed to get fec tool: \""<< m_fecToolName<< "\""<< endreq;
00188 return StatusCode::FAILURE;
00189 }
00190 info()<< "Added tool "<< m_fecToolName<< endreq;
00191
00192
00193 for(vector<string>::size_type ind = 0; ind < m_trigToolNames.size(); ind++)
00194 {
00195 string tgr = m_trigToolNames[ind];
00196 try
00197 {
00198 m_trigTools.push_back(tool<ITsTriggerTool>(tgr));
00199 }
00200 catch(const GaudiException& exg)
00201 {
00202 fatal()<< "Failed to get Trigger Tool: \""<< tgr<< "\""<< endreq;
00203 return StatusCode::FAILURE;
00204 }
00205 info()<< "Added trigger tool "<< tgr<< endreq;
00206 }
00207 try
00208 {
00209 m_triggerSorter = tool<ITsTriggerTool>(m_trigFilterName);
00210 }
00211 catch(const GaudiException& exg)
00212 {
00213 fatal()<< "Failed to get TriggerFilterTool: \""<< m_trigFilterName<< "\""<< endreq;
00214 return StatusCode::FAILURE;
00215 }
00216
00217
00218 try
00219 {
00220 m_roTrigPackTool = tool<IROsTriggerDataPackerTool>(m_roTrigPackName);
00221 }
00222 catch(const GaudiException& exg)
00223 {
00224 fatal()<< "Failed to get Readout Trigger Package Tool: \""
00225 << m_roTrigPackName<< "\""<< endreq;
00226 return StatusCode::FAILURE;
00227 }
00228
00229 for(vector<string>::size_type ind = 0; ind < m_roToolNames.size(); ind++)
00230 {
00231 string rotool = m_roToolNames[ind];
00232 try
00233 {
00234 m_roTools.push_back(tool<IROsReadoutTool>(rotool));
00235 }
00236 catch(const GaudiException& exg)
00237 {
00238 fatal()<< "Failed to get Readout Tool: \""<< rotool<< "\""<< endreq;
00239 return StatusCode::FAILURE;
00240 }
00241 info()<< "Added readout tool "<< rotool<< endreq;
00242 }
00243
00244 return sc;
00245 }
00246
00247 StatusCode DigitalizeAlg::execute()
00248 {
00249 debug()<< "Digitalization execute()...."<< endreq;
00250
00251
00252 debug()<< "Now get one SimHitHeader & vector of SimHeaders @!"<< endreq;
00253
00254 vector<const SimHeader*> shs;
00255 SimHitHeader* shh = m_preElecSimSvc->getSimHitHeader(shs, m_hitEarliest, m_hitLatest);
00256
00257 debug()<< "HitCollection map size: "<< shh->hitCollection().size()<< endreq;
00258
00259 debug()<< "Now get one ElecHeader!"<< endreq;
00260 ElecHeader* eh = new ElecHeader();
00261 debug()<< "ElecHeader at "<< eh<< "\n"
00262 << "Electronics simulation...."<< endreq;
00263 StatusCode sc = this->ElecSim(shh, shs, eh);
00264 if(sc.isFailure())
00265 {
00266 error()<< "Error in ElecSim():"<< endreq;
00267 return sc;
00268 }
00269 delete shh;
00270
00271
00272
00273
00274
00275
00276
00277 debug()<< "Now get one SimReadout....."<< endreq;
00278 SimReadoutHeader* srh = new SimReadoutHeader();
00279 debug()<< "SimReadoutHeader at "<< srh<< "\n"
00280 << "SimReadout simulation...."<< endreq;
00281 sc = this->TrigExecute(eh, srh);
00282 if(sc.isFailure())
00283 {
00284 error()<< "Error in TrigExecute():"<< endreq;
00285 return sc;
00286 }
00287
00288 sc = this->m_roBufferSvc->setROHeaders(srh);
00289 if(sc.isFailure())
00290 {
00291 error()<< "Error when fill MixHeader buffer!"<< endreq;
00292 return sc;
00293 }
00294
00295
00296 delete eh;
00297
00298 return StatusCode::SUCCESS;
00299 }
00300
00301
00302 StatusCode DigitalizeAlg::ElecSim(const SimHitHeader* shh, vector<const SimHeader*>& shs, ElecHeader*& eh)
00303 {
00304
00305
00306 bool found;
00307 found = false;
00308 vector<const SimHeader*>::size_type ind;
00309 for(ind = 0; ind < shs.size(); ind++)
00310 {
00311
00312 this->AppendInputHeader(shs[ind]);
00313 if(!found)
00314 {
00315 eh->setContext(shs[ind]->context());
00316 found = true;
00317 }
00318 }
00319
00320
00321 debug()<< "Before setContext(): "<< eh->timeStamp().GetSec()
00322 << "--"<< eh->timeStamp().GetNanoSec()<< endreq;
00323
00324 m_hitEarliest.Add(-preTimeTolerance/CLHEP::second);
00325 m_hitLatest.Add(postTimeTolerance/CLHEP::second);
00326
00327 eh->setEarliest(m_hitEarliest);
00328 eh->setLatest(m_hitLatest);
00329 eh->setTimeStamp(m_hitEarliest);
00330
00331 debug()<<"After setContext() "<< eh->timeStamp()<< endreq;
00332
00333
00334 ElecPulseHeader* eph = new ElecPulseHeader(eh);
00335 eh->setPulseHeader(eph);
00336
00337
00338 ElecCrateHeader* ech = new ElecCrateHeader(eh);
00339 eh->setCrateHeader(ech);
00340
00341
00342
00343 map<short int, SimHitCollection*> mshc = shh->hitCollection();
00344
00345 debug()<< "Processing SimHit collections: "<< mshc.size()<< endreq;
00346
00347
00348 map<short int, SimHitCollection*>::iterator mit;
00349 for(mit = mshc.begin(); mit != mshc.end(); mit++)
00350 {
00351 Detector det(mit->first);
00352 debug()<< "Checking "<< det.detName()<< " for hits."<< endreq;
00353 SimHitCollection* hits = mit->second;
00354 if(!hits) return StatusCode::FAILURE;
00355
00356 if(det.isAD())
00357 {
00358 const vector<SimHit*> simhits = hits->collection();
00359 for(vector<SimHit*>::const_iterator vit = simhits.begin(); vit != simhits.end(); vit++)
00360 {
00361 AdPmtSensor sensDetId((*vit)->sensDetId());
00362 debug()<< "SimHit properties for PMT: ring: "<< sensDetId.ring()<< " column: "<< sensDetId.column()
00363 << " "<< sensDetId.sensorId()<< endreq;
00364 }
00365 }
00366 else if(det.isWaterShield())
00367 {
00368 const vector<SimHit*> simhits = hits->collection();
00369 for(vector<SimHit*>::const_iterator vit = simhits.begin(); vit != simhits.end(); vit++)
00370 {
00371 PoolPmtSensor sensDetId((*vit)->sensDetId());
00372 debug()<< "SimHit properties for PMT: wallNum: "<< sensDetId.wallNumber()
00373 << " wallSpot: "<< sensDetId.wallSpot() << " "<< sensDetId.sensorId()<< endreq;
00374 }
00375 }
00376
00377 debug()<< "Get hit collection from "<< det.detName()<< " (id = "
00378 << det.siteDetPackedData()<< ") "<< " with "
00379 << hits->collection().size()<< " hits."<< endreq;
00380
00381 StatusCode sc;
00382
00383 if(find(m_detectors.begin(), m_detectors.end(), det) == m_detectors.end())
00384 {
00385 debug()<< "Detector "<< det.detName()<< " need not to be simulated."<< endreq;
00386 continue;
00387 }
00388 if(det.isAD() || det.isWaterShield())
00389 {
00390
00391 debug()<< "Processing PMT hits."<< endreq;
00392 ElecPulseCollection* pulses = new ElecPulseCollection(eph, det);
00393 sc = m_pmtTool->generatePulses(hits, pulses);
00394 if(sc != StatusCode::SUCCESS) return sc;
00395 eph->addPulseCollection(pulses);
00396
00397 ElecFeeCrate* crate = new ElecFeeCrate(det, ech);
00398 sc = m_feeTool->generateSignals(pulses, crate);
00399 if(sc != StatusCode::SUCCESS) return sc;
00400 ech->addCrate(crate);
00401 }
00402 else if(det.detectorId() == DetectorId::kRPC)
00403 {
00404
00405 debug()<< "Processing RPC hits."<< endreq;
00406 ElecPulseCollection* pulses = new ElecPulseCollection(eph, det);
00407 sc = m_rpcTool->generatePulses(hits, pulses);
00408 if(sc != StatusCode::SUCCESS) return sc;
00409 eph->addPulseCollection(pulses);
00410
00411 ElecFecCrate* crate = new ElecFecCrate(det, ech);
00412 sc = m_fecTool->generateSignals(pulses, crate);
00413 if(sc != StatusCode::SUCCESS) return sc;
00414 ech->addCrate(crate);
00415 }
00416 else
00417 {
00418 error()<< "Unknown detector "<< det<< endreq;
00419 return StatusCode::FAILURE;
00420 }
00421 }
00422
00423 info()<< "To grep: (Full Elec) new data pushed out at time "<< m_hitEarliest<< endreq;
00424
00425 return StatusCode::SUCCESS;
00426 }
00427
00428 StatusCode DigitalizeAlg::TrigSim(const ElecHeader& eh, SimTrigHeader*& th)
00429 {
00430 th->setCommandHeader(new SimTrigCommandHeader(th));
00431
00432
00433 th->setContext(eh.context());
00434 th->setTimeStamp(eh.timeStamp());
00435 th->setEarliest(eh.earliest());
00436 th->setLatest(eh.latest());
00437
00438 debug()<< "TrigSim time: "<< endreq;
00439 debug()<< "Earliest: "<< th->earliest().GetSec()<< "--"<< th->earliest().GetNanoSec()<< " "
00440 << "Latest: "<< th->latest().GetSec()<< "--"<< th->latest().GetNanoSec()<< endreq;
00441
00442
00443 for(vector<ITsTriggerTool*>::size_type ind = 0; ind < m_trigTools.size(); ind++)
00444 {
00445 debug()<< "Running trigger tool #"<< ind<< " "<< m_trigToolNames[ind]<< endreq;
00446
00447 StatusCode sc = m_trigTools[ind]->mutate(th, eh);
00448 if(sc.isFailure())
00449 {
00450 fatal()<< "Trigger Tool "<< m_trigToolNames[ind]<< " failed"<< endreq;
00451 delete th;
00452 th = 0;
00453 return StatusCode::FAILURE;
00454 }
00455 }
00456 if(m_triggerSorter->mutate(th, eh).isFailure())
00457 {
00458 fatal()<< "Trigger Tool "<< m_trigFilterName<< " "<< m_triggerSorter<< " failed"<< endreq;
00459 return StatusCode::FAILURE;
00460 }
00461
00462 return StatusCode::SUCCESS;
00463 }
00464
00465 StatusCode DigitalizeAlg::ReadoutSim(const ElecHeader& eh, const SimTrigHeader& th, SimReadoutHeader*& srh)
00466 {
00467 srh->setContext(eh.context());
00468 srh->setTimeStamp(eh.timeStamp());
00469 srh->setEarliest(eh.earliest());
00470 srh->setLatest(eh.latest());
00471
00472 debug()<< "ReadoutSim time: "<< endreq;
00473 debug()<< srh->earliest().GetSec()<< "--"<< srh->earliest().GetNanoSec()<< " "
00474 << srh->latest().GetSec()<< "--"<< srh->latest().GetNanoSec()<< endreq;
00475
00476
00477
00478
00479 debug()<< "Creating Trigger Data Packages."<< endreq;
00480
00481 vector<ReadoutTriggerDataPkg*> trigPkgs;
00482
00483 StatusCode sc = m_roTrigPackTool->fillDataPakages(trigPkgs, th);
00484 if(sc.isFailure())
00485 {
00486 fatal()<< "Readout Tool "<< m_roTrigPackName<< " "<< m_roTrigPackTool<< " failed"<< endreq;
00487 return StatusCode::FAILURE;
00488 }
00489
00490
00491 for(vector<IROsReadoutTool*>::size_type ind = 0; ind < m_roTools.size(); ++ind)
00492 {
00493 debug()<< "Running readout tool #"<< ind<< " "<< m_roToolNames[ind]<< endreq;
00494
00495 sc = m_roTools[ind]->mutate(srh, trigPkgs, eh);
00496 if(sc.isFailure())
00497 {
00498 fatal()<< "Readout Tool "<< m_roToolNames[ind]<< " failed"<< endreq;
00499 delete srh;
00500 srh = 0;
00501 return StatusCode::FAILURE;
00502 }
00503 }
00504
00505 return StatusCode::SUCCESS;
00506 }
00507
00508 StatusCode DigitalizeAlg::TrigExecute(const ElecHeader* eh, SimReadoutHeader*& srh)
00509 {
00510 debug()<< "Running Trigger and Readout Simulation!"<< endreq;
00511
00512 const ElecPulseHeader::PulseCollectionMap& pcmap = eh->pulseHeader()->pulseCollection();
00513 debug()<< "TrigExecute() get "<< pcmap.size()<< " pulse collections:"<< endreq;
00514 ElecPulseHeader::PulseCollectionMap::const_iterator it, done = pcmap.end();
00515 for(it = pcmap.begin(); it != done; ++it)
00516 {
00517 debug()<< "detector: "<< it->first<< " has "<< it->second->pulses().size()<< endreq;
00518 }
00519
00520 SimTrigHeader* th = new SimTrigHeader();
00521 StatusCode sc = this->TrigSim(*eh, th);
00522 if(sc.isFailure() || !th)
00523 {
00524 error()<< "TrigExecute(): Failed to run TrigSim!"<< endreq;
00525 return StatusCode::FAILURE;
00526 }
00527
00528
00529
00530
00531
00532
00533
00534 th->setExecNumber(srh->execNumber());
00535
00536 debug()<< "exec num "<< srh->execNumber()<< endreq;
00537
00538 sc = this->ReadoutSim(*eh, *th, srh);
00539 if(sc.isFailure() || !srh)
00540 {
00541 error()<< "TrigExecute(): Failed to run ReadoutSim"<< endreq;
00542 return StatusCode::FAILURE;
00543 }
00544
00545
00546 delete th;
00547
00548 return StatusCode::SUCCESS;
00549 }
00550
00551 StatusCode DigitalizeAlg::finalize()
00552 {
00553 info()<< "DigitalizeAlg::finalize()...."<< endreq;
00554 this->DybAlgorithm<SimReadoutHeader>::finalize();
00555 return StatusCode::SUCCESS;
00556 }