00001
00007 #include "ValBase.h"
00008
00009 #include "GaudiKernel/MsgStream.h"
00010 #include "GaudiKernel/IDataProviderSvc.h"
00011 #include "GaudiKernel/SmartDataPtr.h"
00012 #include "GaudiKernel/AlgTool.h"
00013 #include "GaudiKernel/ToolFactory.h"
00014 #include "GaudiKernel/IToolSvc.h"
00015 #include "GaudiKernel/IParticlePropertySvc.h"
00016 #include "GaudiKernel/ParticleProperty.h"
00017
00018 #include "Event/TopLevel/EventModel.h"
00019 #include "Event/TopLevel/Event.h"
00020 #include "Event/TopLevel/MCEvent.h"
00021
00022
00023 #include "Event/MonteCarlo/McParticle.h"
00024 #include "Event/MonteCarlo/McIntegratingHit.h"
00025 #include "Event/MonteCarlo/McPositionHit.h"
00026 #include "GlastSvc/MonteCarlo/IMcGetEventInfoTool.h"
00027 #include "GlastSvc/MonteCarlo/IMcGetTrackInfoTool.h"
00028
00029 #include <algorithm>
00030
00037 class McAnalValsTool : public ValBase
00038 {
00039 public:
00040
00041 McAnalValsTool( const std::string& type,
00042 const std::string& name,
00043 const IInterface* parent);
00044
00045 virtual ~McAnalValsTool() { }
00046
00047 StatusCode initialize();
00048
00049 StatusCode calculate();
00050
00051 private:
00053 void calcMcAngleInfo(const Event::McParticle* mcPart, const Event::McParticle* mcGamma,
00054 double& ang2Gam, double& cls2Gam, double& mcTrkRms, double& prtType,
00055 double& prtEnergy, double& prtCosDirX, double& prtCosDirY, double& prtCosDirZ,
00056 double& prtNHits, double& prtNClstrs, double& prtNGaps, double& prt1stGapSz,
00057 double& prtNHits2Gp);
00058
00059 void calcMcEnergyInfo(const Event::McParticle* mcPart,
00060 double& lastHitE, double& radLossE, double& dltaRayE, double& nBrems,
00061 double& nDeltas, double&nDeltaHt, double& aveRange, double& maxRange);
00062
00063
00064 double m_numCalls;
00065
00066
00067 double m_prmEnergy;
00068 double m_prmPosX;
00069 double m_prmPosY;
00070 double m_prmPosZ;
00071 double m_prmCosDirX;
00072 double m_prmCosDirY;
00073 double m_prmCosDirZ;
00074 double m_prmDecEne;
00075 double m_prmDecPosX;
00076 double m_prmDecPosY;
00077 double m_prmDecPosZ;
00078 double m_prmDecCosX;
00079 double m_prmDecCosY;
00080 double m_prmDecCosZ;
00081 double m_prmNDghtrs;
00082 double m_prmDecCode;
00083
00084 double m_prmDecLayer;
00085 double m_prmDecInCnv;
00086
00087 double m_prmNumSecndry;
00088 double m_prmNumAsscted;
00089 double m_prmTrkPattern;
00090 double m_prmMcAngle;
00091 double m_prmClsAngle;
00092
00093
00094 double m_scd1Type;
00095 double m_scd1FirstLyr;
00096 double m_scd1LastLyr;
00097 double m_scd1Energy;
00098 double m_scd1CosDirX;
00099 double m_scd1CosDirY;
00100 double m_scd1CosDirZ;
00101 double m_scd1NHits;
00102 double m_scd1NClstrs;
00103 double m_scd1NGaps;
00104 double m_scd11stGapSz;
00105 double m_scd1NHits2Gp;
00106 double m_scd1McTrkRms;
00107 double m_scd1Ang2Gam;
00108 double m_scd1Cls2Gam;
00109 double m_scd1ELastHit;
00110 double m_scd1RadELoss;
00111 double m_scd1DeltaRay;
00112 double m_scd1NBrems;
00113 double m_scd1NDeltas;
00114 double m_scd1NDeltaHt;
00115 double m_scd1AveRange;
00116 double m_scd1MaxRange;
00117
00118
00119 double m_scd2Type;
00120 double m_scd2FirstLyr;
00121 double m_scd2LastLyr;
00122 double m_scd2Energy;
00123 double m_scd2CosDirX;
00124 double m_scd2CosDirY;
00125 double m_scd2CosDirZ;
00126 double m_scd2NHits;
00127 double m_scd2NClstrs;
00128 double m_scd2NGaps;
00129 double m_scd21stGapSz;
00130 double m_scd2NHits2Gp;
00131 double m_scd2McTrkRms;
00132 double m_scd2Ang2Gam;
00133 double m_scd2Cls2Gam;
00134 double m_scd2ELastHit;
00135 double m_scd2RadELoss;
00136 double m_scd2DeltaRay;
00137 double m_scd2NBrems;
00138 double m_scd2NDeltas;
00139 double m_scd2NDeltaHt;
00140 double m_scd2AveRange;
00141 double m_scd2MaxRange;
00142
00143
00144 IParticlePropertySvc* m_ppsvc;
00145
00146
00147 IMcGetEventInfoTool* m_mcEvent;
00148 IMcGetTrackInfoTool* m_mcTracks;
00149 };
00150
00151
00152 static ToolFactory<McAnalValsTool> s_factory;
00153 const IToolFactory& McAnalValsToolFactory = s_factory;
00154
00155
00156 McAnalValsTool::McAnalValsTool(const std::string& type,
00157 const std::string& name,
00158 const IInterface* parent)
00159 : ValBase( type, name, parent )
00160 {
00161
00162 declareInterface<IValsTool>(this);
00163 }
00164
00233 StatusCode McAnalValsTool::initialize()
00234 {
00235 StatusCode sc = StatusCode::SUCCESS;
00236
00237 MsgStream log(msgSvc(), name());
00238
00239 if( ValBase::initialize().isFailure()) return StatusCode::FAILURE;
00240
00241
00242 if( serviceLocator() ) {
00243 if( service("ParticlePropertySvc", m_ppsvc, true).isFailure() ) {
00244 log << MSG::ERROR << "Service [ParticlePropertySvc] not found" << endreq;
00245 }
00246 } else {
00247 return StatusCode::FAILURE;
00248 }
00249
00250
00251 m_mcEvent = 0;
00252 sc = toolSvc()->retrieveTool("McGetEventInfoTool", m_mcEvent);
00253 if (sc.isFailure()) {
00254 log << MSG::INFO << " McGetEventInfoTool not found" << endreq;
00255 log << MSG::INFO << " Will not generate McAnalVals" << endreq;
00256 return StatusCode::SUCCESS;
00257 }
00258
00259 m_mcTracks = 0;
00260 sc = toolSvc()->retrieveTool("McGetTrackInfoTool", m_mcTracks);
00261 if (sc.isFailure()) {
00262 log << MSG::INFO << " McGetTrackInfoTool not found!" << endreq;
00263 log << MSG::INFO << " Will not generate McAnalVals" << endreq;
00264 return StatusCode::SUCCESS;
00265 }
00266
00267
00268
00269 addItem("McaNumCalls", &m_numCalls);
00270 addItem("McaPrmEnergy", &m_prmEnergy);
00271 addItem("McaPrmDecEne", &m_prmDecEne);
00272 addItem("McaDecPosX", &m_prmPosX);
00273 addItem("McaDecPosY", &m_prmPosY);
00274 addItem("McaDecPosZ", &m_prmPosZ);
00275 addItem("McaPrmDecPosX", &m_prmDecPosX);
00276 addItem("McaPrmDecPosY", &m_prmDecPosY);
00277 addItem("McaPrmDecPosZ", &m_prmDecPosZ);
00278 addItem("McaPrmCosDirX", &m_prmCosDirX);
00279 addItem("McaPrmCosDirY", &m_prmCosDirY);
00280 addItem("McaPrmCosDirZ", &m_prmCosDirZ);
00281 addItem("McaPrmDecCosX", &m_prmDecCosX);
00282 addItem("McaPrmDecCosY", &m_prmDecCosY);
00283 addItem("McaPrmDecCosZ", &m_prmDecCosZ);
00284 addItem("McaPrmNDghtrs", &m_prmNDghtrs);
00285 addItem("McaPrmDecCode", &m_prmDecCode);
00286
00287
00288 addItem("McaPrmNumSecndry", &m_prmNumSecndry);
00289 addItem("McaPrmNumAsscted", &m_prmNumAsscted);
00290 addItem("McaPrmTrkPattern", &m_prmTrkPattern);
00291 addItem("McaPrmMcAngle", &m_prmMcAngle);
00292 addItem("McaPrmClsAngle", &m_prmClsAngle);
00293
00294 addItem("McaPrmDecLayer", &m_prmDecLayer);
00295 addItem("McaPrmDecInCnv", &m_prmDecInCnv);
00296
00297 addItem("McaScd1PartType", &m_scd1Type);
00298 addItem("McaScd1FirstLyr", &m_scd1FirstLyr);
00299 addItem("McaScd1LastLyr", &m_scd1LastLyr);
00300 addItem("McaScd1Energy", &m_scd1Energy);
00301 addItem("McaScd1CosDirX", &m_scd1CosDirX);
00302 addItem("McaScd1CosDirY", &m_scd1CosDirY);
00303 addItem("McaScd1CosDirZ", &m_scd1CosDirZ);
00304 addItem("McaScd1NHits", &m_scd1NHits);
00305 addItem("McaScd1NClstrs", &m_scd1NClstrs);
00306 addItem("McaScd1NGaps", &m_scd1NGaps);
00307 addItem("McaScd11stGapSz", &m_scd11stGapSz);
00308 addItem("McaScd1NHits2Gp", &m_scd1NHits2Gp);
00309 addItem("McaScd1McTrkRms", &m_scd1McTrkRms);
00310 addItem("McaScd1Ang2Gam", &m_scd1Ang2Gam);
00311 addItem("McaScd1Cls2Gam", &m_scd1Cls2Gam);
00312 addItem("McaScd1ELastHit", &m_scd1ELastHit);
00313 addItem("McaScd1RadEloss", &m_scd1RadELoss);
00314 addItem("McaScd1DeltaRay", &m_scd1DeltaRay);
00315 addItem("McaScd1NBrems", &m_scd1NBrems);
00316 addItem("McaScd1NDeltas", &m_scd1NDeltas);
00317 addItem("McaScd1NDeltaHt", &m_scd1NDeltaHt);
00318 addItem("McaScd1AveRange", &m_scd1AveRange);
00319 addItem("McaScd1MaxRange", &m_scd1MaxRange);
00320
00321 addItem("McaScd2PartType", &m_scd2Type);
00322 addItem("McaScd2FirstLyr", &m_scd2FirstLyr);
00323 addItem("McaScd2LastLyr", &m_scd2LastLyr);
00324 addItem("McaScd2Energy", &m_scd2Energy);
00325 addItem("McaScd2CosDirX", &m_scd2CosDirX);
00326 addItem("McaScd2CosDirY", &m_scd2CosDirY);
00327 addItem("McaScd2CosDirZ", &m_scd2CosDirZ);
00328 addItem("McaScd2NHits", &m_scd2NHits);
00329 addItem("McaScd2NClstrs", &m_scd2NClstrs);
00330 addItem("McaScd2NGaps", &m_scd2NGaps);
00331 addItem("McaScd21stGapSz", &m_scd21stGapSz);
00332 addItem("McaScd2NHits2Gp", &m_scd2NHits2Gp);
00333 addItem("McaScd2McTrkRms", &m_scd2McTrkRms);
00334 addItem("McaScd2Ang2Gam", &m_scd2Ang2Gam);
00335 addItem("McaScd2Cls2Gam", &m_scd2Cls2Gam);
00336 addItem("McaScd2ELastHit", &m_scd2ELastHit);
00337 addItem("McaScd2RadEloss", &m_scd2RadELoss);
00338 addItem("McaScd2DeltaRay", &m_scd2DeltaRay);
00339 addItem("McaScd2NBrems", &m_scd2NBrems);
00340 addItem("McaScd2NDeltas", &m_scd2NDeltas);
00341 addItem("McaScd2NDeltaHt", &m_scd2NDeltaHt);
00342 addItem("McaScd2AveRange", &m_scd2AveRange);
00343 addItem("McaScd2MaxRange", &m_scd2MaxRange);
00344
00345 zeroVals();
00346
00347 return sc;
00348 }
00349
00350
00351 StatusCode McAnalValsTool::calculate()
00352 {
00353 StatusCode sc = StatusCode::SUCCESS;
00354 MsgStream log( msgSvc(), name() );
00355
00356 if (m_mcEvent==0 || m_mcTracks==0) return sc;
00357
00358
00359 SmartDataPtr<Event::EventHeader> header(m_pEventSvc, EventModel::EventHeader);
00360 SmartDataPtr<Event::MCEvent> mcheader(m_pEventSvc, EventModel::MC::Event);
00361 SmartDataPtr<Event::McParticleCol> particles(m_pEventSvc, EventModel::MC::McParticleCol);
00362
00363 double t = header->time();
00364 log << MSG::DEBUG << "Event time: " << t << endreq;;
00365
00366 if (m_mcEvent)
00367 {
00368
00369 int classifyBits = m_mcEvent->getClassificationBits();
00370
00371
00372 const Event::McParticle* mcPart = m_mcEvent->getPrimaryParticle();
00373 const Event::McParticle* mcMain = 0;
00374 const Event::McParticle* mcSecond = 0;
00375
00376 idents::VolumeIdentifier curVolId = const_cast<Event::McParticle*>(mcPart)->getFinalId();
00377 CLHEP::HepLorentzVector primary4mom = mcPart->initialFourMomentum();
00378
00379
00380 m_prmEnergy = primary4mom.e();
00381 m_prmDecEne = mcPart->finalFourMomentum().e();
00382 m_prmPosX = mcPart->initialPosition().x();
00383 m_prmPosY = mcPart->initialPosition().y();
00384 m_prmPosZ = mcPart->initialPosition().z();
00385 m_prmCosDirX = primary4mom.vect().unit().x();
00386 m_prmCosDirY = primary4mom.vect().unit().y();
00387 m_prmCosDirZ = primary4mom.vect().unit().z();
00388 m_prmDecPosX = mcPart->finalPosition().x();
00389 m_prmDecPosY = mcPart->finalPosition().y();
00390 m_prmDecPosZ = mcPart->finalPosition().z();
00391 m_prmDecCosX = mcPart->finalFourMomentum().vect().unit().x();
00392 m_prmDecCosY = mcPart->finalFourMomentum().vect().unit().y();
00393 m_prmDecCosZ = mcPart->finalFourMomentum().vect().unit().z();
00394 m_prmDecCode = classifyBits;
00395 m_prmNDghtrs = mcPart->daughterList().size();
00396 m_prmNumSecndry = m_mcEvent->getNumSecondaries();
00397 m_prmNumAsscted = m_mcEvent->getNumAssociated();
00398
00399
00400 if (classifyBits & Event::McEventStructure::CHARGED)
00401 {
00402
00403 curVolId = const_cast<Event::McParticle*>(mcPart)->getInitialId();
00404
00405
00406 mcMain = mcPart;
00407 }
00408
00409 else if (classifyBits & Event::McEventStructure::GAMMA)
00410 {
00411 primary4mom = mcPart->finalFourMomentum();
00412
00413
00414 if (m_prmNumSecndry > 0)
00415 {
00416 double mcMainE = 0.;
00417 double mcSecondE = 0.;
00418
00419
00420
00421
00422 for(int idx = 0; idx < m_prmNumSecndry; idx++)
00423 {
00424 const Event::McParticle* mcPart1 = m_mcEvent->getSecondary(idx);
00425
00426
00427
00428 if (classifyBits & Event::McEventStructure::TRKCONVERT && mcPart1->getProcess() != "conv")
00429 continue;
00430
00431
00432 if (mcMain)
00433 {
00434 mcSecond = mcPart1;
00435 mcSecondE = mcPart1->initialFourMomentum().e();
00436
00437
00438 if (mcMainE < mcSecondE)
00439 {
00440 mcSecond = mcMain;
00441 mcSecondE = mcMainE;
00442 mcMain = mcPart1;
00443 mcMainE = mcPart1->initialFourMomentum().e();
00444 }
00445 }
00446 else
00447 {
00448 mcMain = mcPart1;
00449 mcMainE = mcPart1->initialFourMomentum().e();
00450 }
00451 }
00452 }
00453 }
00454
00455
00456 if (curVolId[0] == 0 && curVolId[3] == 1 && curVolId.size() > 3)
00457 {
00458 m_prmDecLayer = 19;
00459
00460 if (curVolId.size() > 6)
00461 {
00462 int trayNum = curVolId[4];
00463 int botTop = curVolId[6];
00464
00465 m_prmDecInCnv = botTop;
00466 m_prmDecLayer = trayNum;
00467 }
00468 }
00469
00470
00471 if (mcMain)
00472 {
00473
00474 CLHEP::Hep3Vector mainVec = m_mcEvent->getTrackDirection(mcMain);
00475 CLHEP::HepLorentzVector main4mom = mcMain->initialFourMomentum();
00476 double mainMom = main4mom.vect().mag();
00477 CLHEP::HepLorentzVector main4cls(mainMom*mainVec,main4mom.e());
00478
00479
00480 calcMcAngleInfo(mcMain, mcPart, m_scd1Ang2Gam, m_scd1Cls2Gam, m_scd1McTrkRms, m_scd1Type,
00481 m_scd1Energy, m_scd1CosDirX, m_scd1CosDirY, m_scd1CosDirZ, m_scd1NHits, m_scd1NClstrs,
00482 m_scd1NGaps, m_scd11stGapSz, m_scd1NHits2Gp);
00483
00484
00485 calcMcEnergyInfo(mcMain, m_scd1ELastHit, m_scd1RadELoss, m_scd1DeltaRay,
00486 m_scd1NBrems, m_scd1NDeltas, m_scd1NDeltaHt, m_scd1AveRange, m_scd1MaxRange);
00487
00488
00489
00490
00491
00492
00493
00494
00495 m_scd1FirstLyr = m_mcEvent->getTrackHitLayer(mcMain, 0);
00496 m_scd1LastLyr = m_mcEvent->getTrackHitLayer(mcMain, 100);
00497
00498 if (m_scd1RadELoss > m_scd1Energy - m_scd1ELastHit)
00499 {
00500
00501 }
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512 if (mcSecond)
00513 {
00514 CLHEP::Hep3Vector secondVec = m_mcEvent->getTrackDirection(mcSecond);
00515 CLHEP::HepLorentzVector scnd4mom = mcSecond->initialFourMomentum();
00516 double scndMom = scnd4mom.vect().mag();
00517 CLHEP::HepLorentzVector scnd4cls(scndMom*secondVec,scnd4mom.e());
00518
00519 calcMcAngleInfo(mcSecond, mcPart, m_scd2Ang2Gam, m_scd2Cls2Gam, m_scd2McTrkRms, m_scd2Type,
00520 m_scd2Energy, m_scd2CosDirX, m_scd2CosDirY, m_scd2CosDirZ, m_scd2NHits, m_scd2NClstrs,
00521 m_scd2NGaps, m_scd21stGapSz, m_scd2NHits2Gp);
00522
00523 calcMcEnergyInfo(mcSecond, m_scd2ELastHit, m_scd2RadELoss, m_scd2DeltaRay,
00524 m_scd2NBrems, m_scd2NDeltas, m_scd2NDeltaHt, m_scd2AveRange, m_scd2MaxRange);
00525
00526 m_scd2FirstLyr = m_mcEvent->getTrackHitLayer(mcSecond, 0);
00527 m_scd2LastLyr = m_mcEvent->getTrackHitLayer(mcSecond, 100);
00528
00529
00530 unsigned int sharedInfo = m_mcEvent->getSharedHitInfo(mcMain,mcSecond);
00531
00532
00533 m_prmTrkPattern = sharedInfo >> 4;
00534
00535
00536 main4mom += scnd4mom;
00537 main4cls += scnd4cls;
00538 }
00539
00540
00541 double cosMcGamAng = main4mom.vect().unit().dot(primary4mom.vect().unit());
00542 double cosClsGamAng = main4cls.vect().unit().dot(primary4mom.vect().unit());
00543
00544 if (cosMcGamAng > 1.0 ) cosMcGamAng = 1.0;
00545 if (cosClsGamAng > 1.0) cosClsGamAng = 1.0;
00546
00547 m_prmMcAngle = acos(cosMcGamAng);
00548 m_prmClsAngle = acos(cosClsGamAng);
00549
00550 if (m_prmMcAngle > 0.0001)
00551 {
00552
00553 }
00554 }
00555 else
00556 {
00557
00558 }
00559 }
00560
00561 log << MSG::DEBUG << " returning. " << endreq;
00562
00563 return sc;
00564 }
00565
00566
00567 void McAnalValsTool::calcMcAngleInfo(const Event::McParticle* mcPart, const Event::McParticle* mcGamma,
00568 double& ang2Gam, double& cls2Gam, double& mcTrkRms, double& prtType,
00569 double& prtEnergy, double& prtCosDirX, double& prtCosDirY, double& prtCosDirZ,
00570 double& prtNHits, double& prtNClstrs, double& prtNGaps, double& prt1stGapSz,
00571 double& prtNHits2Gp)
00572 {
00573 CLHEP::Hep3Vector mainVec = m_mcEvent->getTrackDirection(mcPart);
00574 CLHEP::HepLorentzVector main4mom = mcPart->initialFourMomentum();
00575 double mainMom = main4mom.vect().mag();
00576 CLHEP::HepLorentzVector main4cls(mainMom*mainVec,main4mom.e());
00577 double cosAng2Gam = main4mom.vect().unit().dot(mcGamma->initialFourMomentum().vect().unit());
00578
00579 if (ang2Gam < -1.)
00580 {
00581 ang2Gam = -1.;
00582 }
00583 if (ang2Gam > 1.)
00584 {
00585 ang2Gam = 1.;
00586 }
00587 ang2Gam = acos(cosAng2Gam);
00588
00589 cosAng2Gam = main4cls.vect().unit().dot(mcPart->initialFourMomentum().vect().unit());
00590 cls2Gam = acos(cosAng2Gam);
00591
00592 mcTrkRms = m_mcEvent->getTrackStraightness(mcPart);
00593
00594 prtType = mcPart->particleProperty();
00595 prtEnergy = main4mom.e();
00596 prtCosDirX = main4mom.vect().unit().x();
00597 prtCosDirY = main4mom.vect().unit().y();
00598 prtCosDirZ = main4mom.vect().unit().z();
00599
00600 prtNHits = (m_mcEvent->getMcPartTrack(mcPart)).size();
00601 prtNClstrs = m_mcEvent->getNumClusterHits(mcPart);
00602 prtNGaps = m_mcEvent->getNumGaps(mcPart);
00603
00604
00605 if (prtNGaps > 0)
00606 {
00607 prt1stGapSz = m_mcEvent->getGapSize(mcPart, 0);
00608 prtNHits2Gp = m_mcEvent->getGapStartHitNo(mcPart, 0) - 1;
00609 }
00610
00611 return;
00612 }
00613
00614 void McAnalValsTool::calcMcEnergyInfo(const Event::McParticle* mcPart,
00615 double& lastHitE, double& radLossE, double& dltaRayE, double& nBrems,
00616 double& nDeltas, double& nDeltaHt, double& aveRange, double& maxRange)
00617 {
00618 int nBremsInt,nDeltasInt,nDeltaHtInt;
00619
00620 lastHitE = m_mcEvent->getTrackELastHit(mcPart);
00621 radLossE = m_mcEvent->getTrackBremELoss(mcPart, nBremsInt);
00622 dltaRayE = m_mcEvent->getTrackDeltaELoss(mcPart, nDeltasInt, nDeltaHtInt);
00623 nDeltas = m_mcEvent->getTrackDeltaRange(mcPart, aveRange, maxRange);
00624
00625 nBrems = nBremsInt;
00626 nDeltas = nDeltasInt;
00627 nDeltaHt = nDeltaHtInt;
00628
00629 return;
00630 }
00631