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