00001
00008
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;
00042 const int _nLayers = 18;
00043 const unsigned int _unset = (unsigned int) -1;
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
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;
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
00173 static ToolFactory<GltValsTool> s_factory;
00174 const IToolFactory& GltValsToolFactory = s_factory;
00175
00176
00177 GltValsTool::GltValsTool(const std::string& type,
00178 const std::string& name,
00179 const IInterface* parent)
00180 : ValBase( type, name, parent )
00181 {
00182
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
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
00211
00212 addItem("GltWord", &Trig_word);
00213 addItem("GltGemSummary", &Trig_GemSummary);
00214 addItem("GltEventFlags", &Trig_evtFlags);
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
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
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
00286 Trig_gemprescale = pEvent->gemPrescale();
00287 Trig_gltprescale = pEvent->gltPrescale();
00288 Trig_prescaleexpired = pEvent->prescaleExpired();
00289 }
00290
00291
00292
00293
00294 Trig_word = word & enums::GEM_mask;
00295
00296 Trig_GemSummary = (word >> enums::GEM_offset) & enums::GEM_mask;
00297
00298 Trig_engine = (word >> (2*enums::GEM_offset)) & enums::GEM_mask;
00299
00300 unsigned int Trig_gltengine = word2 & enums::ENGINE_mask;
00301
00302 if (Trig_gltengine != enums::ENGINE_unset) Trig_engine = Trig_gltengine;
00303 Trig_gemengine = ((word2 >> enums::ENGINE_offset) & enums::ENGINE_mask);
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
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
00330 if(!pClusters) return sc;
00331
00332 bool three_in_a_row = ((word & enums::b_Track)!=0);
00333
00334 int tower, layer;
00335
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
00346 if (pClusters && three_in_a_row)
00347 {
00348
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
00363 for(hit=0; hit<x_hitCount; ++hit){
00364 tower = xHitList[hit]->tower();
00365 x_hits[tower][layer]++;
00366 }
00367
00368 for(hit=0; hit<y_hitCount; ++hit){
00369 tower = yHitList[hit]->tower();
00370 y_hits[tower][layer]++;
00371 }
00372 }
00373 }
00374
00375
00376
00377 int nTotTrigs = 0;
00378 int nTowerTrigs = 0;
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
00400
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
00409
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) {
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
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) {
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
00476 CLHEP::HepMatrix U(3,3);
00477 U = diagonalize(&moments);
00478
00479
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
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 }