00001
00002
00003
00004
00005 #include "GaudiKernel/MsgStream.h"
00006 #include "GaudiKernel/AlgFactory.h"
00007 #include "GaudiKernel/IDataProviderSvc.h"
00008 #include "GaudiKernel/SmartDataPtr.h"
00009 #include "GaudiKernel/Algorithm.h"
00010
00011
00012 #include "ntupleWriterSvc/INTupleWriterSvc.h"
00013
00014 #include "instrument/DetectorConverter.h"
00015 #include "instrument/Scintillator.h"
00016 #include "instrument/SiDetector.h"
00017 #include "instrument/CsIDetector.h"
00018 #include "instrument/Tower.h"
00019 #include "idents/ModuleId.h"
00020 #include "idents/XtalId.h"
00021
00022
00023 #include "GlastEvent/data/TdGlastData.h"
00024
00025
00026 #include "GlastSvc/GlastDetSvc/IGlastDetSvc.h"
00027 #include "xml/IFile.h"
00028
00029 #include <cassert>
00030 #include <iomanip>
00031
00032 static inline bool three_in_a_row(unsigned bits)
00033 {
00034 while( bits ) {
00035 if( (bits & 7) ==7) return true;
00036 bits >>= 1;
00037 }
00038 return false;
00039 }
00040 static inline unsigned layer_bit(int layer){ return 1 << layer;}
00041
00042
00050 class Level1 : public Algorithm {
00051 public:
00052 enum {
00053
00054 b_ACDL = 1,
00055 b_ACDH = 2,
00056 b_Track= 4,
00057 b_CAL= 8,
00058 b_HI_CAL= 16
00059
00060 };
00061 Level1(const std::string& name, ISvcLocator* pSvcLocator);
00062 StatusCode initialize();
00063 StatusCode execute();
00064 StatusCode finalize();
00065
00066
00067
00068 void setId( idents::ModuleId id){m_id=id;}
00069 void cal(const CsIDetector& );
00070 void acd(const Scintillator& );
00071 void tkr(const SiDetector& );
00072
00073 private:
00074
00076 IGlastDetSvc* m_detSvc;
00078 INTupleWriterSvc *m_ntupleWriteSvc;
00080 std::string m_tupleName;
00081
00082 idents::ModuleId m_id;
00083 unsigned m_mask;
00084
00086 #if 0
00087 std::vector<unsigned long> m_xbits, m_ybits;
00088 #else
00089 unsigned long m_xbits[16];
00090 unsigned long m_ybits[16];
00091 #endif
00092
00093 int m_acd_hits;
00094 int m_log_hits;
00095 bool m_local;
00096 bool m_hical;
00097 unsigned m_hical_bits[16];
00098
00100 double m_tray_spacing;
00101 double m_z_first_plane;
00102 int m_planes;
00103 double m_LOCAL_threshold;
00104 double m_HICAL_threshold;
00105 };
00106
00107
00108
00109
00110
00111
00112 static const AlgFactory<Level1> Factory;
00113 const IAlgFactory& Level1Factory = Factory;
00114
00115
00117
00118 :Algorithm(name, pSvcLocator)
00119 , m_detSvc(0)
00120 {
00121
00122 declareProperty("tupleName", m_tupleName="");
00123 declareProperty("mask" , m_mask=0xffffffff);
00124 }
00125
00126
00128
00129 StatusCode sc = StatusCode::SUCCESS;
00130 MsgStream log(msgSvc(), name());
00131 log << MSG::INFO << "initialize: Level1.mask= "<< std::setbase(16) << m_mask;
00132 if( m_mask==0) log << " (so inoperative)" ;
00133 log <<endreq;
00134
00135
00136 setProperties();
00137
00138
00139 if (service("GlastDetSvc", m_detSvc).isFailure()){
00140 log << MSG::ERROR << "Couldn't find the GlastDetSvc!" << endreq;
00141 return StatusCode::FAILURE;
00142 }
00143
00144
00145 xml::IFile * ini = const_cast<xml::IFile*>(m_detSvc->iniFile());
00146 assert(4==ini->getInt("glast", "xNum"));
00147 m_tray_spacing = ini->getDouble("tracker","tray_spacing");
00148 m_z_first_plane = ini->getDouble("tracker","z_first_plane");
00149 m_planes = ini->getInt("tracker","num_trays")-1;
00150 m_LOCAL_threshold = ini->getDouble("trigger","LOCAL_threshold");
00151 m_HICAL_threshold = ini->getDouble("trigger","HICAL_threshold");
00152
00153
00154
00155 if (service("ntupleWriterSvc", m_ntupleWriteSvc).isFailure()) {
00156 log << MSG::ERROR << "Failed to get the ntupleWriterSvc" << endreq;
00157 return StatusCode::FAILURE;
00158 }
00159
00160 return sc;
00161 }
00162
00163
00165
00166 {
00167 StatusCode sc = StatusCode::SUCCESS;
00168 MsgStream log( msgSvc(), name() );
00169
00170
00171 m_acd_hits=0;
00172 m_log_hits=0;
00173 m_local=m_hical=false;
00174 for(int k=0; k<16; ++k) m_hical_bits[k]=0;
00175
00176 #if 0
00177 m_xbits.clear(); m_xbits.resize(m_planes);
00178 m_ybits.clear(); m_ybits.resize(m_planes);
00179 #else
00180 for(int i=0; i<16; ++i) m_xbits[i]=m_ybits[i]=0;
00181 #endif
00182
00183 class TriggerAnalyzer : public DetectorConverter {
00184 public:
00185 TriggerAnalyzer(Level1* ta):m_ta(ta){}
00186
00187 void forward (const Tower& t) { m_ta->setId( t.getId());}
00188
00189 void forward ( const CsIDetector& csi_det) { if( !(csi_det.empty()) ) m_ta->cal(csi_det); }
00190 void forward ( const SiDetector& si_det) { if( !(si_det.empty()) ) m_ta->tkr(si_det); }
00191 void forward ( const Scintillator& scint) { if( !(scint.empty()) ) m_ta->acd(scint); }
00192 Level1* m_ta;
00193 } trig(this);
00194
00195 m_detSvc->accept(trig);
00196
00197
00198 bool triggered=false;
00199 for( int j=0; j<16; ++j) {
00200 unsigned and_bits= m_xbits[j] & m_ybits[j];
00201 triggered = triggered || three_in_a_row(and_bits);
00202 m_hical = m_hical || three_in_a_row(m_hical_bits[j]);
00203 }
00204
00205
00206 unsigned trigger_bits = 0;
00207 if( m_acd_hits>0 ) trigger_bits |= Level1::b_ACDL;
00208 if( m_acd_hits>2 ) trigger_bits |= Level1::b_ACDH;
00209 if( triggered) trigger_bits |= Level1::b_Track;
00210 if( m_local) trigger_bits |= Level1::b_CAL;
00211 if( m_hical) trigger_bits |= Level1::b_HI_CAL;
00212
00213
00214
00215
00216 if( m_mask!=0 && ( trigger_bits & m_mask) == 0) {
00217 setFilterPassed( false );
00218 log << MSG::INFO << "Event did not trigger" << endreq;
00219 m_ntupleWriteSvc->storeRowFlag(false);
00220 }else {
00221 log << MSG::INFO << "Event triggered, masked bits = "
00222 << std::setbase(16) << (m_mask==0?trigger_bits:trigger_bits& m_mask) << endreq;
00223 if(!m_tupleName.empty() ) sc = m_ntupleWriteSvc->addItem(m_tupleName.c_str(), "Trig_Bits", trigger_bits );
00224 }
00225
00226 return sc;
00227 }
00228
00230
00231 {
00232 CoordTransform T = plane.localToGlobal();
00233 Point p(0,0,0); p.transform(T);
00234 int layer = static_cast<int>(((p.z() - m_z_first_plane)/m_tray_spacing) + 0.5);
00235 unsigned int planebit = layer_bit(layer);
00236
00237 bool x=plane.isXplane();
00238 if( x) m_xbits[m_id] |= planebit;
00239 else m_ybits[m_id] |= planebit;
00240 }
00241
00242 void Level1::acd(const Scintillator& tile)
00243 {
00244 m_acd_hits++;
00245 }
00246 void Level1::cal(const CsIDetector& log)
00247 {
00248 m_log_hits++;
00249
00250 if(log.energy()>m_LOCAL_threshold) m_local=true;
00251 if(log.energy()>m_HICAL_threshold){
00252 idents::XtalId logId(log.xtalId());
00253 m_hical_bits[m_id] |= layer_bit(logId.layer());
00254
00255 }
00256 }
00257
00258
00259
00260
00262
00263 StatusCode sc = StatusCode::SUCCESS;
00264 MsgStream log(msgSvc(), name());
00265
00266 return sc;
00267 }
00268
00269
00270