All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
PfoUtilities.cc
Go to the documentation of this file.
1 #include "PfoUtilities.h"
2 
3 #include <CalorimeterHitType.h>
4 #include "marlin/VerbosityLevels.h"
5 
6 #include <EVENT/LCCollection.h>
7 #include <EVENT/MCParticle.h>
8 #include <EVENT/SimTrackerHit.h>
9 #include <EVENT/Track.h>
10 #include <EVENT/TrackerHit.h>
11 
12 #include <IMPL/LCCollectionVec.h>
13 
14 #include <CalorimeterHitType.h>
15 #include <marlinutil/GeometryUtil.h>
16 #include <algorithm>
17 #include <set>
18 
19 float PfoUtil::TimeAtEcal(const Track* pTrack, float& tof) {
20  float bField = MarlinUtil::getBzAtOrigin();
21  const TrackState* pTrackState = pTrack->getTrackState(TrackState::AtCalorimeter);
22 
23  //locationAtEcal in mm
24  const float* locationAtECal = pTrackState->getReferencePoint();
25  HelixClass helix;
26  helix.Initialize_Canonical(pTrack->getPhi(), pTrack->getD0(), pTrack->getZ0(), pTrack->getOmega(), pTrack->getTanLambda(),
27  bField);
28 
29  //time-of-flight is distance divided by c=300mm/ns
30  tof = sqrt(locationAtECal[0] * locationAtECal[0] + locationAtECal[1] * locationAtECal[1] +
31  locationAtECal[2] * locationAtECal[2]) /
32  300;
33 
34  //HelixClass::getDistanceToPoint(float const* xPoint, float * Distance) returns
35  //a time computed as distance/momentum
36  float distance[3] = {0.0, 0.0, 0.0};
37  float minTime = helix.getDistanceToPoint(locationAtECal, distance);
38 
39  const float px = helix.getMomentum()[0];
40  const float py = helix.getMomentum()[1];
41  const float pz = helix.getMomentum()[2];
42  //139MeV is mass of pion
43  const float E = sqrt(px * px + py * py + pz * pz + 0.139 * 0.139);
44  minTime = minTime / 300 * E - tof;
45 
46  return minTime;
47 }
48 
49 void PfoUtil::GetClusterTimes(const Cluster* cluster, float& meanTime, int& nCaloHitsUsed, float& meanTimeEcal, int& nEcal,
50  float& meanTimeHcalEndcap, int& nHcalEnd, bool correctHitTimesForTimeOfFlight) {
51  float sumTimeEnergy(0.f);
52  float sumEnergy(0.f);
53  float sumEnergyEcal(0.f);
54  float sumTimeEnergyEcal(0.f);
55  float sumEnergyHcalEndcap(0.f);
56  float sumTimeEnergyHcalEndcap(0.f);
57  meanTime = std::numeric_limits<float>::max();
58  meanTimeEcal = std::numeric_limits<float>::max();
59  meanTimeHcalEndcap = std::numeric_limits<float>::max();
60  nEcal = 0;
61  nHcalEnd = 0;
62  nCaloHitsUsed = 0;
63 
64  CalorimeterHitVec hits = cluster->getCalorimeterHits();
65  std::vector<float> hittimes;
66  std::vector<float> tofCorrections;
67  std::vector<float> deltaTimes;
68 
69  for (unsigned int ihit = 0; ihit < hits.size(); ++ihit) {
70  // optionally correct hit times for straight line tof (may have already been done in another processor)
71  if (correctHitTimesForTimeOfFlight) {
72  const float x = hits[ihit]->getPosition()[0];
73  const float y = hits[ihit]->getPosition()[1];
74  const float z = hits[ihit]->getPosition()[2];
75  const float r = sqrt(x * x + y * y + z * z);
76  const float tof = r / 300.;
77  tofCorrections.push_back(tof);
78  hittimes.push_back(hits[ihit]->getTime() - tof);
79  } else {
80  hittimes.push_back(hits[ihit]->getTime());
81  }
82  }
83 
84  std::sort(hittimes.begin(), hittimes.end());
85 
86  int iMedian = static_cast<int>(hits.size() / 2.);
87  float medianTime = hittimes[iMedian];
88  // streamlog_out( MESSAGE ) << " Median time : " << medianTime << std::endl;
89 
90  for (unsigned int ihit = 0; ihit < hits.size(); ++ihit)
91  deltaTimes.push_back(fabs(hittimes[ihit] - medianTime));
92  std::sort(deltaTimes.begin(), deltaTimes.end());
93 
94  unsigned ihit90 = 0;
95 
96  if (hits.size() > 1) {
97  ihit90 = static_cast<int>((hits.size() * 9) / 10.);
98  if (ihit90 >= hits.size() - 1)
99  ihit90 = hits.size() - 2;
100  } else {
101  ihit90 = 0;
102  }
103 
104  // streamlog_out( MESSAGE ) << " hits " << hits.size() << " hit 90 = " << ihit90 << std::endl;
105  float deltaMedian = deltaTimes[ihit90] + 0.1;
106  // streamlog_out( MESSAGE ) << " deltaMedian : " << deltaMedian << std::endl;
107 
108  for (unsigned int ihit = 0; ihit < hits.size(); ++ihit) {
109  CalorimeterHit* hit = hits[ihit];
110  float hitTime = hits[ihit]->getTime();
111  if (correctHitTimesForTimeOfFlight)
112  hitTime -= tofCorrections[ihit];
113 
114  if ((hitTime - medianTime) < deltaMedian) {
115  sumEnergy += hit->getEnergy();
116  sumTimeEnergy += hit->getEnergy() * hitTime;
117  nCaloHitsUsed++;
118  // streamlog_out( MESSAGE ) << " Using : " << hit->getEnergy() << " : " << hit->getTime() << std::endl;
119 
120  CHT ch = hit->getType();
121  if (ch.is(CHT::ecal)) {
122  nEcal++;
123  sumEnergyEcal += hit->getEnergy();
124  sumTimeEnergyEcal += hit->getEnergy() * hitTime;
125  } else {
126  // float z = hit->getPosition()[2];
127  if (!ch.is(CHT::barrel)) {
128  nHcalEnd++;
129  sumEnergyHcalEndcap += hit->getEnergy();
130  sumTimeEnergyHcalEndcap += hit->getEnergy() * hitTime;
131  }
132  }
133  } else {
134  // streamlog_out( MESSAGE ) << " notus : " << hit->getEnergy() << " : " << hit->getTime() << std::endl;
135  }
136  }
137 
138  if (sumEnergy > 0.f)
139  meanTime = sumTimeEnergy / sumEnergy;
140  if (sumEnergyEcal > 0.f)
141  meanTimeEcal = sumTimeEnergyEcal / sumEnergyEcal;
142  if (sumEnergyHcalEndcap > 0.f)
143  meanTimeHcalEndcap = sumTimeEnergyHcalEndcap / sumEnergyHcalEndcap;
144 
145  // streamlog_out( MESSAGE ) << "Tot En. = " << sumEnergy << " in ECAL: sum = " << sumEnergyEcal << ", nClu = " << nEcal << "\n"
146  // << " " << " in HcalEnd: sum = " << sumEnergyHcalEndcap << ", nHcalEndClu = " << nHcalEnd << std::endl;
147 
148  return;
149 }
float TimeAtEcal(const Track *pTrack, float &tof)
Definition: PfoUtilities.cc:19
void GetClusterTimes(const Cluster *cluster, float &meanTime, int &nCaloHitsUsed, float &meanTimeEcal, int &nEcal, float &meanTimeHcalEndcap, int &nHcalEnd, bool correctHitTimesForTimeOfFlight)
Definition: PfoUtilities.cc:49