Main Page | Namespace List | Class Hierarchy | Compound List | File List | Compound Members | File Members | Related Pages

GltValsTool.cxx

Go to the documentation of this file.
00001 
00008 // Include files
00009 
00010 #include "ValBase.h"
00011 
00012 #include "GaudiKernel/MsgStream.h"
00013 #include "GaudiKernel/IDataProviderSvc.h"
00014 #include "GaudiKernel/SmartDataPtr.h"
00015 #include "GaudiKernel/AlgTool.h"
00016 #include "GaudiKernel/ToolFactory.h"
00017 #include "GaudiKernel/IToolSvc.h"
00018 #include "GaudiKernel/GaudiException.h" 
00019 
00020 #include "TkrUtil/ITkrGeometrySvc.h"
00021 #include "TkrUtil/ITkrQueryClustersTool.h"
00022 #include "idents/TowerId.h"
00023 
00024 #include "Event/TopLevel/EventModel.h"
00025 #include "Event/TopLevel/Event.h"
00026 #include "LdfEvent/EventSummaryData.h"
00027 #include "LdfEvent/LsfMetaEvent.h"
00028 #include "LdfEvent/Gem.h"
00029 #include "CLHEP/Matrix/Matrix.h"
00030 #include "CLHEP/Matrix/SymMatrix.h"
00031 
00032 #include "enums/TriggerBits.h"
00033 
00040 namespace {
00041     const int _nTowers = 16; // maximum possible number of towers
00042     const int _nLayers = 18; // maximum possible number of layers
00043     const unsigned int _unset   = (unsigned int) -1; // default for some of the variables
00044 }
00045 
00046 class GltValsTool : public ValBase
00047 {
00048 public:
00049 
00050     GltValsTool( const std::string& type, 
00051         const std::string& name, 
00052         const IInterface* parent);
00053 
00054     virtual ~GltValsTool() { }
00055 
00056     StatusCode initialize();
00057 
00058     StatusCode calculate();
00059 
00060     void zeroVals();
00061 
00062 private:
00064     ITkrGeometrySvc*       m_tkrGeom;
00065 
00066     //TkrClusters Tuple Items
00067     float Trig_word;
00068     float Trig_GemSummary;
00069     float Trig_evtFlags;
00070     float Trig_tower;
00071     float Trig_xTower;
00072     float Trig_yTower; 
00073     float Trig_layer;
00074     float Trig_total; 
00075     float Trig_numTowers;
00076     float Trig_type; // was: 1= corner, 2 = side, 3 = core, now number of exposed sides (0-4)
00077     float Trig_moment; 
00078     float Trig_zDir; 
00079     int   Trig_engine;
00080     int   Trig_gemengine;
00081     int   Trig_gltprescale;
00082     int   Trig_gemprescale;
00083     int   Trig_prescaleexpired;
00084     int   Trig_sourcegps;
00085     int   Trig_gemDeltaEventTime;
00086     int   Trig_gemDeltaWindowOpenTime;
00087     int   Trig_eventSize;
00088     int   Trig_compressedEventSize;
00089 
00090     ITkrQueryClustersTool* m_clusTool;
00091 };
00092 
00172 // Static factory for instantiation of algtool objects
00173 static ToolFactory<GltValsTool> s_factory;
00174 const IToolFactory& GltValsToolFactory = s_factory;
00175 
00176 // Standard Constructor
00177 GltValsTool::GltValsTool(const std::string& type, 
00178                          const std::string& name, 
00179                          const IInterface* parent)
00180                          : ValBase( type, name, parent )
00181 {    
00182     // Declare additional interface
00183     declareInterface<IValsTool>(this); 
00184 }
00185 
00186 StatusCode GltValsTool::initialize()
00187 {
00188     StatusCode sc = StatusCode::SUCCESS;
00189 
00190     MsgStream log(msgSvc(), name());
00191 
00192     if( ValBase::initialize().isFailure()) return StatusCode::FAILURE;
00193 
00194     // get the services
00195     StatusCode fail = StatusCode::FAILURE;
00196     if( serviceLocator() ) {       
00197         if(service( "TkrGeometrySvc", m_tkrGeom, true ).isFailure()) {
00198             log << MSG::ERROR << "Could not find TkrGeometrySvc" << endreq;
00199             return fail;
00200         }
00201     } else {
00202         return fail;
00203     }
00204 
00205     if ((sc = toolSvc()->retrieveTool("TkrQueryClustersTool", m_clusTool)).isFailure())
00206     {
00207         throw GaudiException("Service [TkrQueryClustersTool] not found", name(), sc);
00208     }
00209 
00210     // load up the map
00211 
00212     addItem("GltWord",       &Trig_word);
00213     addItem("GltGemSummary", &Trig_GemSummary);
00214     addItem("GltEventFlags", &Trig_evtFlags);    // new
00215     addItem("GltTower",      &Trig_tower); 
00216     addItem("GltXTower",     &Trig_xTower);
00217     addItem("GltYTower",     &Trig_yTower);
00218     addItem("GltLayer",      &Trig_layer); 
00219     addItem("GltTotal",      &Trig_total);
00220     addItem("GltNumTowers",  &Trig_numTowers);
00221     addItem("GltType",       &Trig_type);  
00222     addItem("GltMoment",     &Trig_moment);
00223     addItem("GltZDir",       &Trig_zDir);  
00224     addItem("GltEngine",     &Trig_engine);  
00225     addItem("GltGemEngine",  &Trig_gemengine);
00226     addItem("GltGemDeltaEventTime",      &Trig_gemDeltaEventTime);
00227     addItem("GltGemDeltaWindowOpenTime", &Trig_gemDeltaWindowOpenTime);
00228     addItem("GltEnginePrescale",         &Trig_gltprescale);
00229     addItem("GltGemEnginePrescale",      &Trig_gemprescale);
00230     addItem("GltPrescaleExpired",        &Trig_prescaleexpired);
00231     addItem("GltSourceGps",              &Trig_sourcegps);
00232 
00233     addItem("GltEventSize",              &Trig_eventSize);
00234     addItem("GltCompressedEventSize",    &Trig_compressedEventSize);
00235 
00236     zeroVals();
00237 
00238     return sc;
00239 }
00240 
00241 void GltValsTool::zeroVals()
00242 {
00243     ValBase::zeroVals();
00244 
00245     Trig_gemprescale     = _unset;
00246     Trig_gltprescale     = _unset;
00247     Trig_prescaleexpired = _unset;
00248     Trig_gemDeltaEventTime      = -1;
00249     Trig_gemDeltaWindowOpenTime = -1;
00250 }
00251 
00252 StatusCode GltValsTool::calculate()
00253 {
00254     StatusCode sc = StatusCode::SUCCESS;
00255 
00256     // m_pEventSvc already checked by doCalcIfNotDone, no need to repeat
00257 
00258     int nLayers  = m_tkrGeom->numLayers();
00259     int nXTowers = m_tkrGeom->numXTowers();
00260     int nYTowers = m_tkrGeom->numYTowers();
00261     int nTowers  = nXTowers*nYTowers;
00262 
00263 
00264     int iTrig_tower  = -1;
00265     int iTrig_layer  = -1;
00266     int iTrig_xTower = -1;
00267     int iTrig_yTower = -1; 
00268     int iTrig_type   =  0;
00269 
00270     Trig_layer  = iTrig_layer;
00271     Trig_tower  = iTrig_tower;
00272     Trig_xTower = iTrig_xTower;
00273     Trig_yTower = iTrig_yTower;
00274     Trig_type   = iTrig_type;
00275 
00276     // Recover EventHeader Pointer
00277     SmartDataPtr<Event::EventHeader> 
00278         pEvent(m_pEventSvc, EventModel::EventHeader);
00279     unsigned int word  = 0;
00280     unsigned int word2 = _unset;
00281     
00282     if(pEvent) {
00283     word  = pEvent->trigger();
00284     word2 = pEvent->triggerWordTwo();
00285      // by default, engines are initialized to "_unset"; see zeroVals() above
00286     Trig_gemprescale     = pEvent->gemPrescale();
00287     Trig_gltprescale     = pEvent->gltPrescale();
00288     Trig_prescaleexpired = pEvent->prescaleExpired();
00289     }
00290 
00291     // This is the same as the old GltWord
00292     // actually only 6 bits, but no harm (I think!)  
00293     // note that the trigger word from the header has 3 GEM_offset fields that we unpack here:
00294     Trig_word = word & enums::GEM_mask;  // the GltWord, set for simulation from hits or digis
00295 
00296     Trig_GemSummary = (word >> enums::GEM_offset) & enums::GEM_mask; // the GEM condition word, same as previous if simulation
00297     
00298     Trig_engine = (word >> (2*enums::GEM_offset)) & enums::GEM_mask; // the trigger engine number
00299 
00300     unsigned int Trig_gltengine = word2 & enums::ENGINE_mask;
00301     // If the engine number is set, then we will store this one from the TrgConfigSvc in the tuple
00302     if (Trig_gltengine != enums::ENGINE_unset) Trig_engine = Trig_gltengine;
00303     Trig_gemengine = ((word2 >> enums::ENGINE_offset) & enums::ENGINE_mask); // GEM trigger engine number
00304 
00305     SmartDataPtr<LsfEvent::MetaEvent> 
00306         metaTds(m_pEventSvc, "/Event/MetaEvent");
00307     if(metaTds) {
00308         Trig_sourcegps =  metaTds->time().current().sourceGps();
00309         Trig_compressedEventSize = metaTds->compressedSize();
00310     }
00311 
00312     SmartDataPtr<LdfEvent::EventSummaryData> 
00313         eventSummary(m_pEventSvc, "/Event/EventSummary"); 
00314     if(eventSummary) {
00315         Trig_evtFlags =  eventSummary->eventFlags();
00316         Trig_eventSize = eventSummary->eventSizeInBytes();
00317     }
00318 
00319     // GemDeltaTimes
00320     SmartDataPtr<LdfEvent::Gem> gemTds(m_pEventSvc, "/Event/Gem");
00321     if(gemTds) {
00322         Trig_gemDeltaEventTime      = gemTds->deltaEventTime();
00323         Trig_gemDeltaWindowOpenTime = gemTds->deltaWindowOpenTime();
00324     }
00325 
00326     SmartDataPtr<Event::TkrClusterCol>   
00327         pClusters(m_pEventSvc,EventModel::TkrRecon::TkrClusterCol);
00328 
00329     // everything from here on out uses Clusters
00330     if(!pClusters) return sc;
00331 
00332     bool three_in_a_row = ((word & enums::b_Track)!=0);
00333 
00334     int tower, layer;
00335     // needs to be recast into an indexed vector maybe
00336     short x_hits[_nTowers][_nLayers]; 
00337     short y_hits[_nTowers][_nLayers]; 
00338     for(tower=0; tower<_nTowers; ++tower) {
00339         for(layer=0; layer<_nLayers; ++layer){
00340             x_hits[tower][layer]=0;
00341             y_hits[tower][layer]=0;
00342         }
00343     }
00344 
00345     //Search for x-y paired layer.... 
00346     if (pClusters && three_in_a_row)
00347     {
00348         // Make a hit count per plane, per tower.  
00349         layer = nLayers;
00350         while(layer--)
00351         {
00352             Event::TkrClusterVec xHitList = 
00353                 m_clusTool->getClusters(idents::TkrId::eMeasureX,layer);
00354             Event::TkrClusterVec yHitList = 
00355                 m_clusTool->getClusters(idents::TkrId::eMeasureY,layer);
00356 
00357             int x_hitCount = xHitList.size(); 
00358             int y_hitCount = yHitList.size();
00359             if(x_hitCount > 0 && y_hitCount > 0) {
00360 
00361                 int hit;
00362                 // x hits
00363                 for(hit=0; hit<x_hitCount; ++hit){
00364                     tower = xHitList[hit]->tower();
00365                     x_hits[tower][layer]++; 
00366                 }
00367                 // y hits
00368                 for(hit=0; hit<y_hitCount; ++hit){
00369                     tower = yHitList[hit]->tower();
00370                     y_hits[tower][layer]++;
00371                 }
00372             }
00373         }
00374 
00375         // Now search for the 3-in-a-rows (need to look for x & y hits in each...)
00376         // If more than one tower triggers, use the one with the highest layer number
00377         int nTotTrigs = 0;   // total number of possible triggers
00378         int nTowerTrigs = 0; // total number of towers that could trigger
00379         for(tower = 0; tower<nTowers; ++tower) {
00380             int nTrigsThis = 0;
00381             for(layer=0; layer<nLayers-2; ++layer){
00382                 if( (x_hits[tower][layer]   > 0 && y_hits[tower][layer]   > 0 ) &&
00383                     (x_hits[tower][layer+1] > 0 && y_hits[tower][layer+1] > 0 ) &&
00384                     (x_hits[tower][layer+2] > 0 && y_hits[tower][layer+2] > 0 )) 
00385                 {
00386                     nTrigsThis++;
00387                     if(layer > iTrig_layer) {
00388                         iTrig_layer = layer;
00389                         iTrig_tower = tower;
00390                     }
00391                 }
00392             }
00393             nTotTrigs += nTrigsThis;
00394             if(nTrigsThis>0) nTowerTrigs++;
00395         }
00396         Trig_total  = nTotTrigs;
00397         Trig_numTowers = nTowerTrigs;
00398 
00399         // Now classify according to tower type
00400         // new classification is number of exposed sides
00401         if(iTrig_tower >= 0) {
00402             iTrig_type = m_tkrGeom->getTowerType(iTrig_tower);
00403             idents::TowerId towerId = idents::TowerId(iTrig_tower);
00404             iTrig_xTower = towerId.ix();
00405             iTrig_yTower = towerId.iy();
00406         }
00407 
00408         // Now find the average location of all hits
00409         // This is probably too coarse to be useful
00410         double x_sum, y_sum, z_sum, wts, g1, g2, L11, L12, L22, zmax, zmin;
00411         x_sum = y_sum = z_sum = wts = g1 = g2 = L11 = L12 = L22 = 0.;
00412         zmax = 0.;
00413         zmin = 20.; 
00414         CLHEP::HepSymMatrix moments(3,0); 
00415 
00416         if(iTrig_tower >= 0) {
00417             for(tower = 0; tower<_nTowers; ++tower) {
00418                 idents::TowerId towerId = idents::TowerId(tower);
00419                 int ix = towerId.ix();
00420                 int iy = towerId.iy();
00421                 if (ix+1==nXTowers || iy+1==nYTowers) continue;
00422                 for(layer=0; layer<nLayers; ++layer){
00423                     int x_counts = x_hits[tower][layer];
00424                     int y_counts = y_hits[tower][layer];
00425                     double weight = x_counts+y_counts;
00426                     if(x_counts>0 && y_counts>0) { // Don't count random noise hits
00427                         wts += weight;
00428                         double x = (ix+1)*5.;
00429                         double y = (iy+1)*5.;
00430                         double z = (layer+1);
00431                         x_sum += x * weight;
00432                         y_sum += y * weight;
00433                         z_sum += z * weight;
00434                         g1    += 1.;
00435                         g2    += z;
00436                         L11   += 1./weight;
00437                         L12   += z /weight;
00438                         L22   += z*z/weight; 
00439                         if(zmax < z ) zmax = z;
00440                         if(zmin > z ) zmin = z; 
00441 
00442                     }
00443                 }
00444             }
00445 
00446             // Now form moment tensor, etc..... 
00447             if(wts > 0) {
00448                 x_sum /= wts;
00449                 y_sum /= wts;
00450                 z_sum /= wts;
00451                 for(tower = 0; tower<_nTowers; ++tower) {
00452                     idents::TowerId towerId = idents::TowerId(tower);
00453                     int ix = towerId.ix();
00454                     int iy = towerId.iy();
00455                     if (ix+1==nXTowers || iy+1==nYTowers) continue;
00456                     for(layer=0; layer<nLayers-2; ++layer){
00457                         int x_counts = x_hits[tower][layer];
00458                         int y_counts = y_hits[tower][layer];
00459                         double weight = x_counts+y_counts;
00460                         if(x_counts>0 && y_counts>0) { // Don't count random noise hits
00461                             double xres = (ix+1)*5.  - x_sum;
00462                             double yres = (iy+1)*5.  - y_sum;
00463                             double zres = (layer+1)  - z_sum;
00464                             moments(1,1) += xres * xres * weight;
00465                             moments(1,2) += xres * yres * weight;
00466                             moments(1,3) += xres * zres * weight;
00467                             moments(2,2) += yres * yres * weight;
00468                             moments(2,3) += yres * zres * weight;
00469                             moments(3,3) += zres * zres * weight;
00470                         }
00471                     }
00472                 }
00473                 moments /= wts;
00474 
00475                 // Now find transformation to diagonalize
00476                 CLHEP::HepMatrix U(3,3);
00477                 U = diagonalize(&moments);
00478 
00479                 // Now get directions, etc. 
00480                 double Det = L11*L22 - L12*L12;
00481                 if(fabs(Det) > 0) {
00482                     double z_hit_slope = (g2*L11 - g1*L12)/Det;
00483                     Trig_zDir = z_hit_slope*(zmax-zmin)*wts; 
00484                 }
00485                 int sm = 1;
00486                 if(moments(2,2) > moments(1,1))   sm = 2;
00487                 if(moments(3,3) > moments(sm,sm)) sm = 3;
00488 
00489                 Trig_moment = moments(sm,sm);
00490                 //            Vector t_moment(U(1,sm),U(2,sm),U(3,sm));
00491             }
00492         }
00493     }
00494 
00495     Trig_layer  = iTrig_layer;
00496     Trig_tower  = iTrig_tower;
00497     Trig_xTower = iTrig_xTower;
00498     Trig_yTower = iTrig_yTower;
00499     Trig_type   = iTrig_type;
00500 
00501     return sc;
00502 }

Generated on Mon Dec 1 20:09:05 2008 by doxygen 1.3.3