EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SmearTrackingPreview_0_2_B1_5T.cxx
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file SmearTrackingPreview_0_2_B1_5T.cxx
1 // Based on
2 // https://physdiv.jlab.org/DetectorMatrix/
3 // Using everything from v 0.1 from June 16 2020 except:
4 // - EMCal coverage reduced to |eta|<3.5
5 // - Tracking parameters from B=1.5T Matrix preview at
6 // https://indico.bnl.gov/event/9984/contributions/43066/attachments/31173/49186/YR_Detector_Matrix_Tracking_only_10282020.xlsx
7 
8 // Reminder:
9 // Acceptance::Zone(double theta = 0., double = TMath::Pi(),
10 // double phi = 0., double = TMath::TwoPi(),
11 // double E = 0., double = TMath::Infinity(),
12 // double p = 0., double = TMath::Infinity(),
13 // double pt = 0., double = TMath::Infinity(),
14 // double pz = -TMath::Infinity(), double = TMath::Infinity());
15 
16 
19 #include "eicsmear/smear/Device.h"
21 #include "eicsmear/smear/Smearer.h"
24 #include <eicsmear/smear/Smear.h>
26 #include "Math/Vector4D.h"
27 
28 // declare static --> local to this file, won't clash with others
29 static double ThetaFromEta( const double eta );
30 
32  gSystem->Load("libeicsmear");
33 
34  // Create the detector object to hold all devices
35  Smear::Detector det;
36 
37  // The framework provides implementations of three kinematic calculation methods
38  // from smeared values
39  // NM - "Null method" uses the scattered lepton.
40  // DA - Double Angle method
41  // JB - Jacquet-Blondel method
42  // Important Notes:
43  // - All methods rely on measured energy and momentum components (lepton for NM, hadrons for DA, JB).
44  // In order to rely on these methods, you therefore _need_ to cover the relevant
45  // regions with smearers for momentum, angles and energy.
46  // - This is exacerbated by the fact that in the current implementation a smearing of e.g. P
47  // may fool the framework into assuming theta is measured to be the initialization value 0,
48  // leading to nan or inf or otherwise wrong calculations.
49  // NM catches P=0 and replaces it in calculations with E,
50  // but JB and DA either don't work at all or report nonsenical values.
51  // - It may be advantageous to use a P measurement in place of E in a more general case.
52  // In the future, we plan to change to a weighted mean approach.
53  // The summary of the above is that the user should be mindful of the limitations and assumptions in
54  // the calculation of smeared kinematics. Sophisticated calculations are best redone in user code
55  // from the smeared particles directly.
56  det.SetEventKinematicsCalculator("NM DA JB");
57 
58  // Perfect phi and theta for all particles
59  // ---------------------------------------
60  // TODO: Better options?
61  // total coverage of the handbook for tracker, ecal, and hcal is -3.5 < eta < 3.5
62  // muons no longer need special treatment! They are part of kAll
63  Smear::Acceptance::Zone AngleZoneCommon(ThetaFromEta ( 3.5 ),ThetaFromEta ( -3.5 ));
64  Smear::Device SmearThetaCommon(Smear::kTheta, "0.0");
65  SmearThetaCommon.Accept.AddZone(AngleZoneCommon);
66  SmearThetaCommon.Accept.SetGenre(Smear::kAll);
67  det.AddDevice(SmearThetaCommon);
68 
69  Smear::Device SmearPhiCommon(Smear::kPhi, "0.0");
70  SmearPhiCommon.Accept.AddZone(AngleZoneCommon);
71  SmearPhiCommon.Accept.SetGenre(Smear::kAll);
72  det.AddDevice(SmearPhiCommon);
73 
74  // Tracking (B = 1.5 T)
75  // --------
76  // Note: Smear::kCharged checks pdg charge, so includes muons (good)
77  // eta = -3.5 -- -2.5
78  // sigma_p/p ~ 0.2% p + 5%
79  Smear::Acceptance::Zone TrackBack1Zone(ThetaFromEta ( -2.5 ),ThetaFromEta ( -3.5 ));
80  Smear::Device TrackBack1P(Smear::kP, "sqrt( pow ( 0.002*P*P, 2) + pow ( 0.05*P, 2) )");
81  TrackBack1P.Accept.AddZone(TrackBack1Zone);
82  TrackBack1P.Accept.SetCharge(Smear::kCharged);
83  det.AddDevice(TrackBack1P);
84 
85  // eta = -2.5 -- -1
86  // sigma_p/p ~ 0.04% p + 2%
87  Smear::Acceptance::Zone TrackBack2Zone(ThetaFromEta ( -1 ),ThetaFromEta ( -2.5 ));
88  Smear::Device TrackBack2P(Smear::kP, "sqrt( pow ( 0.0004*P*P, 2) + pow ( 0.02*P, 2) )");
89  TrackBack2P.Accept.AddZone(TrackBack2Zone);
90  TrackBack2P.Accept.SetCharge(Smear::kCharged);
91  det.AddDevice(TrackBack2P);
92 
93  // TODO: What to make of this?
94  // "100 MeV/c with 50% acceptance (similar for pi and K)"
95  // Add efficiency?
96  // eta = -1 -- +1
97  // sigma_p/p ~ 0.04% p + 1%
98  Smear::Acceptance::Zone TrackBarrelZone(ThetaFromEta ( 1 ),ThetaFromEta ( -1 ));
99  Smear::Device TrackBarrelP(Smear::kP, "sqrt( pow ( 0.0004*P*P, 2) + pow ( 0.01*P, 2) )");
100  TrackBarrelP.Accept.AddZone(TrackBarrelZone);
101  TrackBarrelP.Accept.SetCharge(Smear::kCharged);
102  det.AddDevice(TrackBarrelP);
103 
104  // eta = 1 -- 2.5
105  // sigma_p/p ~ 0.04% p+2%
106  Smear::Acceptance::Zone TrackFwd2Zone(ThetaFromEta ( 2.5 ),ThetaFromEta ( 1 ));
107  Smear::Device TrackFwd2P(Smear::kP, "sqrt( pow ( 0.0004*P*P, 2) + pow ( 0.02*P, 2) )");
108  TrackFwd2P.Accept.AddZone(TrackFwd2Zone);
109  TrackFwd2P.Accept.SetCharge(Smear::kCharged);
110  det.AddDevice(TrackFwd2P);
111 
112  // eta = 2.5 -- 3.5
113  // sigma_p/p ~ 0.2% p+5%
114  Smear::Acceptance::Zone TrackFwd1Zone(ThetaFromEta ( 3.5 ),ThetaFromEta ( 2.5 ));
115  Smear::Device TrackFwd1P(Smear::kP, "sqrt( pow ( 0.002*P*P, 2) + pow ( 0.05*P, 2) )");
116  TrackFwd1P.Accept.AddZone(TrackFwd1Zone);
117  TrackFwd1P.Accept.SetCharge(Smear::kCharged);
118  det.AddDevice(TrackFwd1P);
119 
120  // EM Calorimeters
121  // ---------------
122  // Note: Smear::kElectromagnetic == gamma + e. Does not include muons (good)
123 
124  // Calorimeter resolution usually given as sigma_E/E = const% + stocastic%/Sqrt{E}
125  // EIC Smear needs absolute sigma: sigma_E = Sqrt{const*const*E*E + stoc*stoc*E}
126 
127  // Back
128  // eta = -3.5 -- -2
129  // stoch. = 2%
130  Smear::Acceptance::Zone EmcalBackZone(ThetaFromEta ( -2 ),ThetaFromEta ( -3.5 ));
131  Smear::Device EmcalBack(Smear::kE, "sqrt( pow ( 0.0*E,2 ) + pow( 0.02,2)*E)");
132  EmcalBack.Accept.AddZone(EmcalBackZone);
134  det.AddDevice(EmcalBack);
135 
136  // MidBack
137  // eta = -2 -- -1
138  // stoch. = 7%
139  Smear::Acceptance::Zone EmcalMidBackZone(ThetaFromEta ( -1 ),ThetaFromEta ( -2 ));
140  Smear::Device EmcalMidBack(Smear::kE, "sqrt( pow ( 0.0*E,2 ) + pow( 0.07,2)*E)");
141  EmcalMidBack.Accept.AddZone(EmcalMidBackZone);
143  det.AddDevice(EmcalMidBack);
144 
145  // Forward
146  // eta = -1 -- 3.5
147  // stoch. = 10-12%, use 12%
148  Smear::Acceptance::Zone EmcalFwdZone(ThetaFromEta ( 3.5 ),ThetaFromEta ( -1 ));
149  Smear::Device EmcalFwd(Smear::kE, "sqrt( pow ( 0.0*E,2 ) + pow( 0.12,2)*E)");
150  EmcalFwd.Accept.AddZone(EmcalFwdZone);
152  det.AddDevice(EmcalFwd);
153 
154  // Could turn on perfect PID
155  // Make sure to not cover more than is covered by the other detectors.
156  // Using the smallest region here, but we could add a second one for
157  // the extended EmCal range
158  // Smear::Acceptance::Zone acceptpid(ThetaFromEta(3.5),ThetaFromEta(-3.5));
159  // Smear::PerfectID pid;
160  // pid.Accept.AddZone(acceptpid);
161  // det.AddDevice( pid );
162 
163  // Hadronic Calorimeters
164  // ----------------------
165  // Note: kHadronic == |pdg|>110.
166 
167  // Back
168  // eta = -3.5 -- -1
169  // stoch. = 50%
170  Smear::Acceptance::Zone HcalBackZone(ThetaFromEta ( -1 ),ThetaFromEta ( -3.5 ));
171  Smear::Device HcalBack(Smear::kE, "sqrt(pow( 0.0*E, 2) + pow ( 0.5,2) *E)");
172  HcalBack.Accept.AddZone(HcalBackZone);
173  HcalBack.Accept.SetGenre(Smear::kHadronic);
174  det.AddDevice(HcalBack);
175 
176  // Barrel
177  // eta = -1 -- 1
178  // The matrix has nothing. As examples, one could turn to
179  // ~CMS
180  // Smear::Device HcalBarrel(Smear::kE, "sqrt( pow( 0.07*E, 2) + pow( 0.85, 2)*E)");
181  // ~Zeus
182  // Smear::Device HcalBarrel(Smear::kE, "sqrt( pow( 0.02*E, 2) + pow( 0.35,2) *E)");
183 
184  // Smear::Acceptance::Zone HcalBarrelZone(ThetaFromEta ( 1 ),ThetaFromEta ( -1 ));
185  // HcalBarrel.Accept.AddZone(HcalBarrelZone);
186  // HcalBarrel.Accept.SetGenre(Smear::kHadronic);
187  // det.AddDevice(HcalBarrel);
188 
189  // Forward
190  // eta = 1 -- 3.5
191  // stoch. = 50%
192  Smear::Acceptance::Zone HcalFwdZone(ThetaFromEta ( 3.5 ),ThetaFromEta ( 1 ));
193  Smear::Device HcalFwd(Smear::kE, "sqrt(pow( 0.0*E, 2) + pow ( 0.5,2) *E)");
194  HcalFwd.Accept.AddZone(HcalFwdZone);
196  det.AddDevice(HcalFwd);
197 
198  // Not covered:
199  // Tracker material budget X/X0 <~5%
200  // Low-Q^2 tagger: -6.9<eta<-5.8: Delta_theta/theta < 1.5%; 10^-6 < Q2 < 10^-2 GeV2
201  // Proton spectrometer: eta>6.2: sigma_intrinsic(|t|)/|t| < 1%; Acceptance: 0.2 < pT < 1.2 GeV/c
202  // Barrel vertexing: sigma_xyz ~ 20 microns, d0(z) ~ d0(r phi) ~ (20 microns)/(pT [GeV]) + 5 microns
203 
204  return det;
205 }
206 
207 // -------------------------------------------------------------------
208 double ThetaFromEta( const double eta ) {
209  if ( !std::isnan(eta) && !std::isinf(eta) ) {
210  return 2.0 * atan( exp( -eta ));
211  }
212  throw std::runtime_error("ThetaFromEta called with NaN or Inf");
213  return -1;
214 }