/search.css" rel="stylesheet" type="text/css"/> /search.js">
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 //Earliest and Latest 00031 TimeStamp initime(0.0); 00032 m_hitEarliest = initime; 00033 m_hitLatest = initime; 00034 //Electronics 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 //Default configuration of the Detectors 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 //Trigger 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 //Readout 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 //ElecSim initialization 00085 //Convert detector names to Detector IDs 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 //Initialize the PreElecSimSvc 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 //Initialize the ROBufferSvc 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 //Get PMT Pulse tool 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 // Get RPC Pulse tool 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 // Get PMT Front-end Electronics tool 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 // Get RPC Front-end Electronics tool 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 //Trigger 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 //Readout 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 //Get one SimHitHeader and a vector of SimHeaders 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 //Get one ElecHeader from ElecSim 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 /*for(vector<const SimHeader*>::size_type i = 0; i < shs.size(); i++) 00271 { 00272 delete shs[i]; 00273 }*/ 00274 00275 //Define output SimReadoutHeader 00276 //Do trigger and readout simulation 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 //this->AppendInputHeader(eh); 00296 delete eh; 00297 00298 return StatusCode::SUCCESS; 00299 } 00300 00301 //ElecSim 00302 StatusCode DigitalizeAlg::ElecSim(const SimHitHeader* shh, vector<const SimHeader*>& shs, ElecHeader*& eh) 00303 { 00304 //Input SimHeaders contributed to the ElecHeader 00305 //Set context as the first SimHeader 00306 bool found; 00307 found = false; 00308 vector<const SimHeader*>::size_type ind; 00309 for(ind = 0; ind < shs.size(); ind++) 00310 { 00311 //at least 1 hit is in use. 00312 this->AppendInputHeader(shs[ind]); 00313 if(!found) 00314 { 00315 eh->setContext(shs[ind]->context()); 00316 found = true; 00317 } 00318 } 00319 00320 //setTimestamp must be after setContext. 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 //Add the pulse header 00334 ElecPulseHeader* eph = new ElecPulseHeader(eh); 00335 eh->setPulseHeader(eph); 00336 00337 //Add the crate header 00338 ElecCrateHeader* ech = new ElecCrateHeader(eh); 00339 eh->setCrateHeader(ech); 00340 00341 //Send each detector's hit collections through ElecSim tool chains 00342 //From the new SimHitHeader. 00343 map<short int, SimHitCollection*> mshc = shh->hitCollection(); 00344 00345 debug()<< "Processing SimHit collections: "<< mshc.size()<< endreq; 00346 00347 //Loop over SimHitCollections in all detectors 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 //Check if this detector should be simulated. 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 //Process PMT hits 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 //Process RPC hits 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 //Set triggers to have same validity range as the crate it belongs to. 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 //Let each tool do its thing on the event 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 //Fill ReadoutHeader With TriggerDataPackage 00477 //With this way of doing it the individual readout tools theoretically 00478 //No longer need to know about the trigger header. 00479 debug()<< "Creating Trigger Data Packages."<< endreq; 00480 //Empty trigger data package object (use tool to fill it) 00481 vector<ReadoutTriggerDataPkg*> trigPkgs; 00482 //Fill trigger data packages 00483 StatusCode sc = m_roTrigPackTool->fillDataPackages(trigPkgs, th); 00484 if(sc.isFailure()) 00485 { 00486 fatal()<< "Readout Tool "<< m_roTrigPackName<< " "<< m_roTrigPackTool<< " failed"<< endreq; 00487 return StatusCode::FAILURE; 00488 } 00489 00490 //Let each tool do its thing on the event 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 //put(th, th->defaultLocation()); 00529 //set input headers 00530 //vector<const IHeader*> iElecHeaders; 00531 //iElecHeaders.push_back(eh); 00532 //th->setInputHeaders(iElecHeaders); 00533 //set execution number 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 // set input headers 00545 //this->AppendInputHeader(th); 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 }