/search.css" rel="stylesheet" type="text/css"/> /search.js">
00001 #include "ROsFecReadoutTool.h" 00002 00003 #include "Conventions/Detectors.h" 00004 #include "Conventions/Trigger.h" 00005 #include "Conventions/Site.h" 00006 #include "Conventions/Electronics.h" 00007 00008 #include "Event/SimReadoutHeader.h" 00009 #include "Event/ReadoutTriggerDataPkg.h" 00010 00011 #include "Event/ElecCrateHeader.h" 00012 #include "Event/ElecFecCrate.h" 00013 00014 #include "Event/SimTrigCommand.h" 00015 #include "Event/SimTrigCommandHeader.h" 00016 #include "Event/SimTrigCommandCollection.h" 00017 00018 ROsFecReadoutTool::ROsFecReadoutTool(const std::string& type, 00019 const std::string& name, 00020 const IInterface* parent) 00021 : GaudiTool(type,name,parent) 00022 { 00023 declareInterface< IROsReadoutTool >(this) ; 00024 // for now add all but RPC's as default. 00025 m_detectorsToProcess.push_back("DayaBayRPC"); 00026 m_detectorsToProcess.push_back("LingAoRPC"); 00027 m_detectorsToProcess.push_back("FarRPC"); 00028 00029 declareProperty("detectorsToProcess",m_detectorsToProcess, 00030 "List of detectors to process with this tool"); 00031 declareProperty("refuseTime",m_refuseTime = 8, 00032 "Time in clk cycles for which FEC will refuse readout"); 00033 declareProperty("readoutWindow",m_readoutWindow = 16, 00034 "Number of clk cycles to OR the signal in each channel when reading out."); 00035 declareProperty("readoutWindowPosition",m_readoutWindowPosition = 8, 00036 "Number of clk cycles to OR the signal in each channel when reading out."); 00037 } 00038 00039 ROsFecReadoutTool::~ROsFecReadoutTool(){} 00040 00041 StatusCode ROsFecReadoutTool::initialize() 00042 { 00043 std::vector<std::string>::iterator it; 00044 for(it=m_detectorsToProcess.begin();it!=m_detectorsToProcess.end();++it){ 00045 short int detId = DayaBay::Detector::siteDetPackedFromString(*it); 00046 DayaBay::Detector det(detId); 00047 m_detectors.insert(det); 00048 } 00049 00050 return StatusCode::SUCCESS; 00051 } 00052 00053 StatusCode ROsFecReadoutTool::finalize() 00054 { 00055 return StatusCode::SUCCESS; 00056 } 00057 00058 StatusCode ROsFecReadoutTool::makeReadouts(DayaBay::SimReadoutHeader* roHeader, 00059 std::vector<DayaBay::ReadoutTriggerDataPkg*>& trigDataPkg, 00060 const DayaBay::ElecHeader& elecHeader) 00061 { 00062 debug() << "running makeReadouts() in ROsFecReadoutTool" << endreq; 00063 00064 DayaBay::SimReadoutHeader::SimReadoutContainer& outputReadouts 00065 = roHeader->readouts(); 00066 00067 Context context = roHeader->context(); 00068 //Get Crate Map 00069 const DayaBay::ElecCrateHeader *ech = elecHeader.crateHeader(); 00070 const DayaBay::ElecCrateHeader::CrateMap crMap = ech->crates(); 00071 DayaBay::ElecCrateHeader::CrateMap::const_iterator crIt; 00072 00073 std::vector<DayaBay::ReadoutTriggerDataPkg*>::iterator pkgIt; 00074 00075 //Loop over All trigger data packages 00076 for(pkgIt = trigDataPkg.begin(); pkgIt != trigDataPkg.end(); ++pkgIt) { 00077 DayaBay::Detector det((*pkgIt)->detector()); 00078 if(m_detectors.find(det) != m_detectors.end()){ 00079 if((*pkgIt)->frames().size()==0){ 00080 fatal() << "makeReadouts(): Trying to process a trigger for " << det.detName() 00081 << " But Package Has No Frames" << endreq; 00082 return StatusCode::FAILURE; 00083 } 00084 00085 crIt = crMap.find(det); 00086 const DayaBay::ElecFecCrate *crate; 00087 if(crIt == crMap.end()){ 00088 fatal() << "makeReadouts(): Trying to process a trigger for " << det.detName() 00089 << " But no crate exists." << endreq; 00090 return StatusCode::FAILURE; 00091 } else { 00092 crate = dynamic_cast<const DayaBay::ElecFecCrate*>(crIt->second); 00093 if (!crate) { // is not fec crate? 00094 fatal() << "makeReadouts(): We are supposed to process FEC crate, but did not get it." 00095 << endreq; 00096 return StatusCode::FAILURE; 00097 } 00098 debug() << "makeReadouts(): Processing a trigger for " << det.detName() 00099 << " found crate at " << crate << endreq; 00100 } 00101 00102 if(crate != 0){ // if the crate exists read it out. 00103 debug()<<"Reading out 1 trigger with: " 00104 <<((*pkgIt)->frames().size())-1 00105 <<" masked triggers."<<endreq; 00106 if (msgLevel(MSG::VERBOSE)) { // Print out list of boards in the ElecCrate 00107 verbose()<<"makeReadouts(): ElecFecCrate: {"<<crate->detector()<<", boards: {"; 00108 DayaBay::ElecFecCrate::FecBoardMap::const_iterator brdIt, brdDone = crate->fecBoards().end(); 00109 for (brdIt = crate->fecBoards().begin(); brdIt != brdDone; brdIt++) { 00110 verbose()<<brdIt->first<<", "; 00111 } 00112 verbose()<<'\x08'<<'\x08'<<"}"<<endreq; 00113 } 00114 00115 const DayaBay::ReadoutRpcTriggerDataFrame *tdf = (*pkgIt)->frames().at(0)->asRpcFrame(); 00116 00117 DayaBay::ReadoutRpcCrate *cr = readoutCrate(tdf,crate,context); 00118 if (!cr) { // could not create readout crate 00119 error()<<"makeReadouts(): Cannot create readout crate."<<endreq; 00120 return StatusCode::FAILURE; 00121 } 00122 outputReadouts.push_back(new DayaBay::SimReadout(cr, 00123 roHeader)); 00124 00126 (*pkgIt)->setReadout(cr); 00127 cr->setTriggerDataPkg(*pkgIt); 00128 if (msgLevel(MSG::VERBOSE)) { 00129 verbose() << "makeReadouts(): Set readout's trigger data package:\n" << (**pkgIt) << endreq; 00130 } 00131 } 00132 }else{ 00133 if (msgLevel(MSG::VERBOSE)) { 00134 verbose() << "Found Trigger For " << det.detName() 00135 << "but this tool is not supposed " 00136 << "to process that detector type " 00137 << "check properties to configure." 00138 << endreq; 00139 } 00140 } 00141 } 00142 00143 if (msgLevel(MSG::VERBOSE)) { 00144 verbose() << "makeReadouts(): ReadoutHeader: " << (*roHeader) <<endreq; 00145 } 00146 00147 return StatusCode::SUCCESS; 00148 } 00149 00150 // provide mutate to satisfy interface IROsReadoutTool. 00151 StatusCode ROsFecReadoutTool::mutate(DayaBay::SimReadoutHeader* roHeader, 00152 std::vector<DayaBay::ReadoutTriggerDataPkg*>& trigDataPkg, 00153 const DayaBay::ElecHeader& elecHeader) 00154 { 00155 debug() << "mutate(): start mutating the ReadoutHeader" << endreq; 00156 StatusCode sc = makeReadouts(roHeader, trigDataPkg, elecHeader); 00157 if (sc.isFailure()) { 00158 return StatusCode::FAILURE; 00159 } else 00160 return StatusCode::SUCCESS; 00161 } 00162 00163 DayaBay::ReadoutRpcCrate* ROsFecReadoutTool::readoutCrate(const DayaBay::ReadoutRpcTriggerDataFrame *tdf, 00164 const DayaBay::ElecFecCrate *cr, Context context) 00165 { 00166 TimeStamp triggerTime(tdf->triggerTime()); 00167 00168 DayaBay::ReadoutRpcCrate *out_readout 00169 = new DayaBay::ReadoutRpcCrate(cr->detector(),0, triggerTime, tdf->triggerType()); 00170 DayaBay::ReadoutRpcCrate::FecReadouts ro_brdMap; 00171 00172 const DayaBay::ElecFecCrate::FecBoardMap& brdMap = cr->fecBoards(); 00173 const std::map< DayaBay::FecChannelId, DayaBay::Trigger::TriggerType_t > 00174 &trigBoards = tdf->outTriggers(); 00175 std::map< DayaBay::FecChannelId, DayaBay::Trigger::TriggerType_t >::const_iterator brdIt; 00176 00177 debug()<<"readoutCrate(): Start looping over "<<trigBoards.size()<<" boards in triggered boards."<<endreq; 00178 for(brdIt = trigBoards.begin(); brdIt != trigBoards.end() ; ++brdIt){ 00179 DayaBay::FecChannelId brdId = brdIt->first; 00180 DayaBay::ElecFecCrate::FecBoardMap::const_iterator elecBrdIt = brdMap.find(brdId); 00181 if (elecBrdIt == brdMap.end()) { // did not find the board in the elec crate 00182 error()<<"readoutCrate(): triggered board, "<<brdId<<"/"<<brdIt->first<<", is not in the current elec crate."<<endreq; 00183 return 0; 00184 } 00185 DayaBay::ReadoutFecBoard *ro_brd = readoutBoard(tdf, &(elecBrdIt->second), context); 00186 00187 if (ro_brd == 0) continue; // test to see if channel has readout 00188 ro_brd->setReadout(out_readout); 00189 ro_brdMap[brdId] = *ro_brd; // copy the value by it's address to the map 00190 ro_brd->setReadout(0); // reset Readout, to avoid double deletion 00191 delete ro_brd; // delete unnecessary copy 00192 } 00193 00194 out_readout->setFecReadouts(ro_brdMap); 00195 return out_readout; 00196 } 00197 00198 DayaBay::ReadoutFecBoard* ROsFecReadoutTool::readoutBoard( 00199 const DayaBay::ReadoutRpcTriggerDataFrame *tdf, 00200 const DayaBay::ElecFecBoard *brd, 00201 Context context) 00202 { 00203 int cycle = tdf->cycle(); 00204 TimeStamp trigTime = tdf->triggerTime(); 00205 // FIXME: check if the trigTime and clock cycle correspond to the simulated window in elec sim. 00206 const DayaBay::ElecFecBoard::ChannelMap& channels = brd->channels(); 00207 DayaBay::ReadoutFecBoard::FecHitmap hm = 0; 00208 DayaBay::FecChannelId brdId = brd->boardId(); 00209 00211 std::map<DayaBay::ElecChannelId, TimeStamp>::iterator muteIt = m_lastRead.find(brdId); 00212 if (muteIt != m_lastRead.end()) { 00213 // triggers should be time ordered, so it should never happen 00214 // that current trigger time would be further in past compared to the last readout 00215 TimeStamp lastRoT = muteIt->second; 00216 lastRoT.Add((double) m_refuseTime / (double) DayaBay::BaseFrequencyHz); 00217 if (lastRoT > trigTime) { // FEC still muted 00218 return 0; 00219 } 00220 } 00221 00223 // loop over channels of this board 00224 DayaBay::ElecFecBoard::ChannelMap::const_iterator chIt, chDone = channels.end(); 00225 debug()<<"readoutBoard(): Start looping over "<<channels.size()<<" channels in elec board "<<brdId<<endreq; 00226 for ( chIt = channels.begin(); chIt != chDone; chIt++) { 00227 // FIXME: check where the cycle is with respect to the simulation window/mainly beginning 00228 // put into higher level! 00229 00230 const DayaBay::DigitalSignal& hits = chIt->second.hits(); 00231 if (msgLevel(MSG::VERBOSE)) { 00232 verbose()<<"Prepare to start looping over "<<hits.size()<<" cycles in the " 00233 <<chIt->first<<" channel's digital signal"<<endreq; 00234 } 00235 // loop over clock cycles in the board and prepare hitmap; 00236 // only in specified readout window 00237 DayaBay::DigitalSignal::const_iterator hitIt, hitDone = hits.end(); 00238 int iteration = 0; 00239 hitIt = hits.begin(); 00240 //unsigned int setbit = 0x1<<(chIt->first.connector()); // Convention: connector starts at 0 00241 unsigned int setbit = chIt->first.fecHit(); 00242 if ( cycle - m_readoutWindowPosition > 0 ) { 00243 hitIt = hitIt + cycle - m_readoutWindowPosition; 00244 } 00245 for ( ; 00246 hitIt < hitDone && iteration <= m_readoutWindow; 00247 hitIt++, iteration++) { 00248 if (*hitIt) { 00249 hm |= setbit; // fill into the hit map 00250 break; 00251 } 00252 } 00253 if (hitIt == hitDone && iteration < m_readoutWindow) { // trigger issued very close to the end of sim window 00254 // FIXME: Put this to the top level - before dealing with boards! 00255 // deal with short simulation window; warning is enough? 00256 } 00257 } 00258 if (msgLevel(MSG::VERBOSE)) { 00259 verbose()<<"ReadoutBoard(): board: "<<brdId<<", hitmap = 0x"<<std::hex << hm << std::dec<<endreq; 00260 } 00261 00262 // the FEC is not muted, let's create its readout 00263 DayaBay::ReadoutFecBoard *ro_brd = new DayaBay::ReadoutFecBoard(brd->boardId(),0); 00264 // check if it is in input triggers and what flag it is given 00265 // FIXME: do it properly, based on the data in readout window, the trigger flags may have changed 00266 std::map< DayaBay::FecChannelId,DayaBay::Trigger::TriggerType_t >::const_iterator 00267 inTrigIt = tdf->inTriggers().find(brdId); 00268 if ( inTrigIt != tdf->inTriggers().end() ) { // the boared has local trigger 00269 if (inTrigIt->second == DayaBay::Trigger::kRPC3of4) { // the trigger is 3 of 4 00270 ro_brd->setFlag3of4(true); 00271 } 00272 ro_brd->setFlag2of4(true); 00273 } 00274 // fill the hitmap 00275 ro_brd->setHitMap(hm); 00276 00277 // Save last readout time 00278 m_lastRead[brdId] = trigTime; 00279 00280 return ro_brd; 00281 }