ATTPCROOT  0.3.0-alpha
A ROOT-based framework for analyzing data from active target detectors
AtPulseLineTask.cxx
Go to the documentation of this file.
1 #include "AtPulseLineTask.h"
2 
3 #include "AtMCPoint.h"
4 #include "AtMap.h"
5 #include "AtSimulatedLine.h"
6 #include "AtSimulatedPoint.h"
7 
8 #include <FairLogger.h>
9 
10 #include <Math/Vector3D.h>
11 #include <Math/Vector3Dfwd.h>
12 #include <TAxis.h>
13 #include <TClonesArray.h>
14 #include <TH1.h>
15 #include <TH2Poly.h>
16 #include <TMath.h>
17 #include <TObject.h>
18 #include <TRandom.h>
19 
20 #include <algorithm>
21 #include <memory>
22 #include <numeric>
23 #include <utility>
24 
25 constexpr auto cRED = "\033[1;31m";
26 constexpr auto cYELLOW = "\033[1;33m";
27 constexpr auto cNORMAL = "\033[0m";
28 constexpr auto cGREEN = "\033[1;32m";
29 
31 {
32  LOG(debug) << "Constructor of AtPulseLineTask";
33 }
34 
36 
37 Int_t AtPulseLineTask::throwRandomAndGetBinAfterDiffusion(const ROOT::Math::XYZVector &loc, Double_t diffusionSigma)
38 {
39  auto r = gRandom->Gaus(0, diffusionSigma);
40  auto phi = gRandom->Uniform(0, TMath::TwoPi());
41  Double_t propX = loc.x() + r * TMath::Cos(phi);
42  Double_t propY = loc.y() + r * TMath::Sin(phi);
43  return fPadPlane->FindBin(propX, propY);
44 }
45 
46 void AtPulseLineTask::generateIntegrationMap(AtSimulatedLine &line)
47 {
48  // MC the integration over the pad plane
49  fXYintegrationMap.clear();
50  auto loc = line.GetPosition();
51  Int_t validPoints = 0;
52 
53  LOG(debug2) << "Sampling with transverse diffusion of: " << line.GetTransverseDiffusion();
54  for (int i = 0; i < fNumIntegrationPoints; ++i) {
55  auto binNumber = throwRandomAndGetBinAfterDiffusion(loc, line.GetTransverseDiffusion());
56 
57  if (binNumber < 0)
58  continue;
59 
60  auto padNumber = fMap->BinToPad(binNumber);
61  fXYintegrationMap[padNumber]++;
62  validPoints++;
63  }
64 
65  for (auto &elem : fXYintegrationMap)
66  elem.second /= (double)validPoints;
67 }
68 
69 bool AtPulseLineTask::gatherElectronsFromSimulatedPoint(AtSimulatedPoint *point)
70 {
71  auto line = dynamic_cast<AtSimulatedLine *>(point);
72  if (line == nullptr) {
73  LOG(fatal) << "Data in branch AtSimulatedPoint is not of type AtSimulatedLine!";
74  return false;
75  }
76 
77  generateIntegrationMap(*line);
78  std::vector<double> zIntegration; // zero is binMin
79  auto binMin = integrateTimebuckets(zIntegration, line);
80 
81  // Now loop through all pads in the integration map, and add electrons
82  for (const auto &pad : fXYintegrationMap) {
83  if (fMap->IsInhibited(pad.first) == AtMap::InhibitType::kTotal)
84  continue;
85 
86  for (int i = 0; i < zIntegration.size(); ++i) {
87  auto zLoc = eleAccumulated[0]->GetXaxis()->GetBinCenter(i + binMin);
88  auto charge = line->GetCharge() * zIntegration[i] * pad.second;
89  auto gAvg = getAvgGETgain(charge);
90  eleAccumulated[pad.first]->Fill(zLoc, gAvg * charge);
91  electronsMap[pad.first] = eleAccumulated[pad.first].get();
92  }
93 
94  if (fIsSaveMCInfo) {
95  auto mcPoint = dynamic_cast<AtMCPoint *>(fMCPointArray->At(line->GetMCPointID()));
96  auto trackID = mcPoint->GetTrackID();
97  saveMCInfo(line->GetMCPointID(), pad.first, trackID);
98  }
99  }
100 
101  return true;
102 }
103 // Returns the bin ID (binMin) that the zIntegral starts from
104 // fills zIntegral with the integral for bins starting with binMin, inclusive
105 Int_t AtPulseLineTask::integrateTimebuckets(std::vector<double> &zIntegral, AtSimulatedLine *line)
106 {
107  zIntegral.clear();
108 
109  // Shift the times by the pad plane location
110  auto tMax = line->GetInitialPosition().z() + fTBPadPlane * fTBTime;
111  auto tMin = line->GetFinalPosition().z() + fTBPadPlane * fTBTime;
112  auto dT = (tMax - tMin);
113  if (dT > fTBTime) {
114  LOG(warn) << "This line charge spans multiple TB widths from " << tMin << " us to " << tMax << " us.";
115  LOG(warn) << " The time distribution is likely widder than will be calculated. dT: " << dT
116  << "ns TB width: " << fTBTime << "ns";
117  }
118 
119  auto tMean = (tMax + tMin) / 2.;
120  auto tIntegrationMinimum = tMin - fNumSigmaToIntegrateZ * line->GetLongitudinalDiffusion();
121  auto tIntegrationMaximum = tMax + fNumSigmaToIntegrateZ * line->GetLongitudinalDiffusion();
122 
123  const TAxis *axis = eleAccumulated[0]->GetXaxis();
124  auto binMin = axis->FindBin(tIntegrationMinimum);
125  auto binMax = axis->FindBin(tIntegrationMaximum);
126  if (binMin < fTBPadPlane)
127  binMin = fTBPadPlane;
128  if (binMax > fTBEntrance)
129  binMax = fTBEntrance;
130 
131  // Integrate G(tMean, sigmaLongDiff) over each time bucket from binMin to binMax
132  // and fill zIntegral with the result.
133  auto denominator = line->GetLongitudinalDiffusion() * TMath::Sqrt(2);
134  double lowerBound = TMath::Erf((axis->GetBinLowEdge(binMin) - tMean) / denominator);
135  for (int i = binMin; i <= binMax; ++i) {
136  auto upperBound = TMath::Erf((axis->GetBinUpEdge(i) - tMean) / denominator);
137  auto integral = 0.5 * (upperBound - lowerBound);
138  zIntegral.emplace_back(integral);
139  lowerBound = upperBound;
140  }
141 
142  // Renormalize the integral if we're up against the pad plane or window
143  if (binMin == fTBPadPlane || binMax == fTBEntrance) {
144  auto sum = std::accumulate(zIntegral.begin(), zIntegral.end(), 0.);
145  for (auto &elem : zIntegral)
146  elem /= sum;
147  }
148 
149  return binMin;
150 }
151 
AtSimulatedLine::GetLongitudinalDiffusion
Double_t GetLongitudinalDiffusion()
Definition: AtSimulatedLine.cxx:57
cGREEN
constexpr auto cGREEN
Definition: AtPulseLineTask.cxx:28
AtPulseLineTask.h
AtSimulatedLine::GetPosition
ROOT::Math::XYZVector GetPosition() override
Definition: AtSimulatedLine.cxx:41
XYZVector
ROOT::Math::XYZVector XYZVector
Definition: AtFindVertex.h:20
AtPulseTask::saveMCInfo
void saveMCInfo(int mcPointID, int padNumber, int trackID)
Definition: AtPulseTask.cxx:122
AtPulseLineTask
Definition: AtPulseLineTask.h:26
AtSimulatedLine::GetTransverseDiffusion
Double_t GetTransverseDiffusion()
Definition: AtSimulatedLine.cxx:53
AtSimulatedPoint::GetMCPointID
std::size_t GetMCPointID()
Definition: AtSimulatedPoint.cxx:50
AtSimulatedLine
Definition: AtSimulatedLine.h:17
AtSimulatedLine.h
AtSimulatedPoint.h
AtSimulatedPoint
Definition: AtSimulatedPoint.h:16
cNORMAL
constexpr auto cNORMAL
Definition: AtPulseLineTask.cxx:27
AtSimulatedLine::GetFinalPosition
ROOT::Math::XYZVector GetFinalPosition()
Definition: AtSimulatedLine.cxx:45
AtPulseTask::fMCPointArray
TClonesArray * fMCPointArray
MC Point Array (input)
Definition: AtPulseTask.h:44
AtMap::InhibitType::kTotal
@ kTotal
cRED
constexpr auto cRED
Definition: AtPulseLineTask.cxx:25
AtMCPoint.h
AtMap.h
cYELLOW
constexpr auto cYELLOW
Definition: AtPulseLineTask.cxx:26
ClassImp
ClassImp(AtPulseLineTask)
AtMCPoint
Definition: AtMCPoint.h:26
AtPulseTask
Definition: AtPulseTask.h:30
AtPulseLineTask::AtPulseLineTask
AtPulseLineTask()
Definition: AtPulseLineTask.cxx:30
AtPulseLineTask::~AtPulseLineTask
~AtPulseLineTask()
AtSimulatedPoint::GetCharge
Int_t GetCharge()
Definition: AtSimulatedPoint.cxx:62
AtSimulatedLine::GetInitialPosition
ROOT::Math::XYZVector GetInitialPosition()
Definition: AtSimulatedLine.cxx:49