Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

Level1.cxx

Go to the documentation of this file.
00001 // $Header: /nfs/slac/g/glast/ground/cvs/trigger/src/Level1.cxx,v 1.6 2001/06/21 20:50:34 burnett Exp $
00002 
00003 // Include files
00004 // Gaudi system includes
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 // ntuple interface
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 // TDS class declarations: input data,
00023 #include "GlastEvent/data/TdGlastData.h"
00024 
00025 // for access to instrument.ini
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 // Define the class here instead of in a header file: not needed anywhere but here!
00042 //------------------------------------------------------------------------------
00050 class Level1 : public Algorithm {
00051 public: 
00052     enum  {
00053            // definition of  trigger bits
00054             b_ACDL =     1,  //  set if cover or side veto, low threshold
00055             b_ACDH =     2,   //  cover or side veto, high threshold
00056             b_Track=     4,   //  3 consecutive x-y layers hit
00057             b_CAL=       8,  //  single log above low threshold
00058             b_HI_CAL=   16   //  3 cal layers in a row above high threshold
00059             
00060     };
00061     Level1(const std::string& name, ISvcLocator* pSvcLocator);
00062     StatusCode initialize();
00063     StatusCode execute();
00064     StatusCode finalize();
00065     
00066     
00067     // call backs to these guys when data found by visitor
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]; // temp to see in debugger!
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 // necessary to define a Factory for this algorithm
00109 // expect that the xxx_load.cxx file contains a call     
00110 //     DLL_DECL_ALGORITHM( Level1 );
00111 
00112 static const AlgFactory<Level1>  Factory;
00113 const IAlgFactory& Level1Factory = Factory;
00114 
00115 //------------------------------------------------------------------------
00117 Level1::Level1(const std::string& name, ISvcLocator* pSvcLocator)
00118 :Algorithm(name, pSvcLocator)
00119 , m_detSvc(0)
00120 {
00121     // declare properties with setProperties calls
00122     declareProperty("tupleName",  m_tupleName="");
00123     declareProperty("mask"     ,  m_mask=0xffffffff); // trigger mask
00124 }
00125 
00126 //------------------------------------------------------------------------
00128 StatusCode Level1::initialize(){
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     // Use the Job options service to set the Algorithm's parameters
00136     setProperties();
00137     
00138     // now try to find the GlastDevSvc service
00139     if (service("GlastDetSvc", m_detSvc).isFailure()){
00140         log << MSG::ERROR << "Couldn't find the GlastDetSvc!" << endreq;
00141         return StatusCode::FAILURE;
00142     }
00143     
00144     // get the ini file and needed constants    
00145     xml::IFile * ini = const_cast<xml::IFile*>(m_detSvc->iniFile());
00146     assert(4==ini->getInt("glast", "xNum"));  // simple check
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     // get a pointer to our ntupleWriterSvc
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 StatusCode Level1::execute()
00166 {
00167     StatusCode  sc = StatusCode::SUCCESS;
00168     MsgStream   log( msgSvc(), name() );
00169     
00170     // initialize counters, flags
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     // define inline visitor class that will walk through the detector tree and call back for data
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     // now process the bits, look for 3-in-a row
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     // set bits in the Level 1 trigger word
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     // apply filter for subsequent processing.
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 void Level1::tkr(const SiDetector& plane)
00231 {
00232     CoordTransform T = plane.localToGlobal(); // for converting the coords following
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 StatusCode Level1::finalize(){
00263     StatusCode  sc = StatusCode::SUCCESS;
00264     MsgStream log(msgSvc(), name());
00265     
00266     return sc;
00267 }
00268 
00269 
00270 

Generated at Wed Nov 21 12:22:27 2001 by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000