/search.css" rel="stylesheet" type="text/css"/> /search.js">
00001 //***************************** 00002 // 00003 // AD Coincidence Tight for Filter 00004 // chao@bnl.gov 2011-07-29 00005 // 00006 //***************************** 00007 00008 #include "ADCoincFilter.h" 00009 00010 #include "Event/HeaderObject.h" 00011 #include "Event/RecHeader.h" 00012 #include "Event/ReadoutHeader.h" 00013 #include "DataSvc/IJobInfoSvc.h" 00014 #include "DataUtilities/DybArchiveList.h" 00015 #include "GaudiKernel/SystemOfUnits.h" 00016 00017 using namespace std; 00018 using namespace Gaudi; 00019 using namespace DayaBay; 00020 00021 ADCoincFilter::ADCoincFilter(const string& name, ISvcLocator* svcloc) 00022 : GaudiAlgorithm(name, svcloc), 00023 m_nTagged(0), m_nSeen(0), m_nKept(0), m_unPhysicalRun(false) 00024 { 00025 declareProperty("RecLocation", m_recHeaderLoc="/Event/Rec/AdSimple", 00026 "the TES path of rec header location"); 00027 declareProperty("TagADLocation", m_tagADLoc="/Event/Tag/Physics/CoincidenceTight", 00028 "the TES path of AD Coincidenc tag header location"); 00029 declareProperty("TagMuonLocation", m_tagMuonLoc="/Event/Tag/Physics/CoincidenceTightRelated", 00030 "the TES path of Correlated Muon tag header location"); 00031 declareProperty("TimeWindow", m_timeWindow=300*Units::microsecond, 00032 "AD coincidence time window"); 00033 declareProperty("MuonVetoWindow", m_muonVetoWindow=10*Units::microsecond, 00034 "muon veto time window"); 00035 declareProperty("MuonKeptWindow", m_muonKeptWindow=300*Units::microsecond, 00036 "muon kept time window"); 00037 declareProperty("MaxCoincFraction", m_maxCoincFraction=0.5, 00038 "maximum allowed coincident trigger fraction"); 00039 } 00040 00041 00042 ADCoincFilter::~ADCoincFilter() 00043 { 00044 } 00045 00046 00047 StatusCode ADCoincFilter::initialize() 00048 { 00049 info() << "initialize: time window: " << m_timeWindow/Units::microsecond << " microseconds" << endreq; 00050 info() << "initialize: veto window: " << m_muonVetoWindow/Units::microsecond << " microseconds" << endreq; 00051 00052 m_jobInfoSvc = svc<IJobInfoSvc>("JobInfoSvc", true); 00053 if(!m_jobInfoSvc) { 00054 error() << "Failed to initialize JobInfoSvc" << endreq; 00055 return StatusCode::FAILURE; 00056 } 00057 00058 // init archive event store 00059 StatusCode sc = service("EventDataArchiveSvc", m_archiveSvc); 00060 if(sc.isFailure()){ 00061 error() << "Failed to access the Archive event store" << endreq; 00062 return sc; 00063 } 00064 00065 // initialize 00066 m_inputHeaders[DetectorId::kAD1] = vector<const IHeader*>(); 00067 m_inputHeaders[DetectorId::kAD2] = vector<const IHeader*>(); 00068 m_inputHeaders[DetectorId::kAD3] = vector<const IHeader*>(); 00069 m_inputHeaders[DetectorId::kAD4] = vector<const IHeader*>(); 00070 00071 return StatusCode::SUCCESS; 00072 } 00073 00074 00075 00076 StatusCode ADCoincFilter::execute() 00077 { 00078 if (m_unPhysicalRun) { 00079 return StatusCode::SUCCESS; // looks like not a physical run, skip. 00080 } 00081 00082 RecHeader* recHeader = get<RecHeader>(m_recHeaderLoc); 00083 if ( !recHeader ) { 00084 warning() << "Cannot find header at " << m_recHeaderLoc << endreq; 00085 return StatusCode::FAILURE; 00086 } 00087 00088 TimeStamp ts = recHeader->context().GetTimeStamp(); 00089 DetectorId::DetectorId_t detectorId = recHeader->context().GetDetId(); 00090 00091 TimeStamp lastTS = ts; 00092 00093 if(m_lastTimeStamp.find(detectorId) != m_lastTimeStamp.end()){ 00094 lastTS = m_lastTimeStamp[detectorId]; 00095 } 00096 m_lastTimeStamp[detectorId] = ts; 00097 00098 // info() << detectorId << " " << ts.GetNanoSec() << endreq; 00099 00100 // only look for AD Coincidence 00101 if ( detectorId == DetectorId::kIWS 00102 || detectorId == DetectorId::kOWS 00103 || detectorId == DetectorId::kRPC) { 00104 return StatusCode::SUCCESS; 00105 } 00106 00107 TimeStamp dt = TimeStamp(ts); 00108 dt.Subtract(lastTS); 00109 if (dt.GetSeconds()*Units::second > m_timeWindow) { 00110 int multiplicity = m_inputHeaders[detectorId].size(); 00111 if (multiplicity < 2) { 00112 // found singles, clear the inputHeaders 00113 m_inputHeaders[detectorId].clear(); 00114 } 00115 else { 00116 // found a gap, save last conincidence's multiplets 00117 HeaderObject *header = new HeaderObject(); 00118 vector<const IHeader*>& inputHeaders = m_inputHeaders[detectorId]; 00119 header->setInputHeaders(inputHeaders); 00120 header->setExecNumber(recHeader->execNumber()); 00121 header->setContext(dynamic_cast<const HeaderObject*>(inputHeaders.at(0))->context()); 00122 header->setEarliest(dynamic_cast<const HeaderObject*>(inputHeaders.at(0))->earliest()); 00123 header->setLatest(dynamic_cast<const HeaderObject*>(inputHeaders.at(inputHeaders.size()-1))->latest()); 00124 header->setJobId(m_jobInfoSvc->currentJobInfo()->jobId()); 00125 00126 put(header, m_tagADLoc); 00127 m_nTagged++; 00128 m_nKept += multiplicity; 00129 // info() << "found one: multiplicty: " << multiplicity << endreq; 00130 00131 00132 // create correlated muon tags 00133 HeaderObject *header2 = new HeaderObject(); 00134 vector<const IHeader*> muonInputHeaders = vector<const IHeader*>(); 00135 DybArchiveList* arcList = get<DybArchiveList*>(m_archiveSvc, "/Event/Readout/ReadoutHeader"); 00136 if(!arcList){ 00137 error() << "Failed to get archive of ReadoutHeader" << endreq; 00138 return StatusCode::FAILURE; 00139 } 00140 TimeStamp firstCoincTS = dynamic_cast<const HeaderObject*>(inputHeaders.at(0))->timeStamp(); 00141 TimeStamp lastCoincTS = dynamic_cast<const HeaderObject*>(inputHeaders.at(inputHeaders.size()-1))->timeStamp(); 00142 for(unsigned int headerIdx=0; headerIdx<arcList->size(); headerIdx++){ 00143 ReadoutHeader* arcHeader = dynamic_cast<ReadoutHeader*>(arcList->dataObject(headerIdx)); 00144 if(!arcHeader) { 00145 error() << "Invalid ReadoutHeader in AES!" << endreq; 00146 return StatusCode::FAILURE; 00147 } 00148 DetectorId::DetectorId_t detId = arcHeader->context().GetDetId(); 00149 if ( detId == DetectorId::kIWS || detId == DetectorId::kOWS || detId == DetectorId::kRPC) { 00150 TimeStamp arcTS = arcHeader->timeStamp(); 00151 TimeStamp dtLastCoinc = TimeStamp(arcTS); 00152 dtLastCoinc.Subtract(lastCoincTS); 00153 TimeStamp dtFirstCoinc = TimeStamp(arcTS); 00154 dtFirstCoinc.Subtract(firstCoincTS); 00155 if (dtLastCoinc.GetSeconds() > 0) { 00156 continue; 00157 } 00158 else if (dtLastCoinc.GetSeconds()*Units::second > -m_muonKeptWindow ) { 00159 // info() << "muon saved: " << detId << " " << arcTS.GetNanoSec() << endreq; 00160 muonInputHeaders.push_back(arcHeader); 00161 } 00162 else { 00163 break; 00164 } 00165 } 00166 } 00167 header2->setInputHeaders(muonInputHeaders); // muonHeaders may be empty 00168 header2->setExecNumber(recHeader->execNumber()); 00169 header2->setContext(recHeader->context()); 00170 header2->setEarliest(recHeader->earliest()); 00171 header2->setLatest(recHeader->latest()); 00172 header2->setJobId(m_jobInfoSvc->currentJobInfo()->jobId()); 00173 put(header2, m_tagMuonLoc); 00174 m_nKeptMuon += muonInputHeaders.size(); 00175 00176 // clear the inputHeaders 00177 m_inputHeaders[detectorId].clear(); 00178 } 00179 } 00180 00181 // muon veto 00182 TimeStamp dt_IWS = TimeStamp(ts); 00183 if(m_lastTimeStamp.find(DetectorId::kIWS) != m_lastTimeStamp.end()){ 00184 dt_IWS.Subtract(m_lastTimeStamp[DetectorId::kIWS]); 00185 } 00186 TimeStamp dt_OWS = TimeStamp(ts); 00187 if(m_lastTimeStamp.find(DetectorId::kOWS) != m_lastTimeStamp.end()){ 00188 dt_OWS.Subtract(m_lastTimeStamp[DetectorId::kOWS]); 00189 } 00190 if (!(dt_IWS*Units::second < m_muonVetoWindow && dt_OWS*Units::second < m_muonVetoWindow)) { 00191 m_inputHeaders[detectorId].push_back(recHeader); 00192 } 00193 00194 // catch unphysical runs 00195 m_nSeen++; 00196 if (float(m_nKept)/m_nSeen > m_maxCoincFraction && m_nSeen > 1000) { 00197 m_unPhysicalRun = true; 00198 warning() << "saw " << m_nKept << " coincident triggers out of " << m_nSeen 00199 << " total. This is unphysical, disabling IBD Filter Tag" << endreq; 00200 } 00201 00202 return StatusCode::SUCCESS; 00203 } 00204 00205 00206 StatusCode ADCoincFilter::finalize() 00207 { 00208 info() << m_nTagged << " multiplets (" << m_nKept << " triggers) tagged at " << m_tagADLoc 00209 << " out of " << m_nSeen << " triggers" << endreq; 00210 info() << m_nKeptMuon << " muon triggers kept"<< endreq; 00211 00212 return StatusCode::SUCCESS; 00213 } 00214