EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SmearMatrixDetector_0_1.cxx
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file SmearMatrixDetector_0_1.cxx
1 // Based on
2 // https://physdiv.jlab.org/DetectorMatrix/
3 // From June 16 2020
4 
5 // W.r.t. to the [Detector Requirements and R&D Handbook](http://www.eicug.org/web/sites/default/files/EIC_HANDBOOK_v1.2.pdf) there have been three changes.
6 
7 // For the Backward Detector the Tracking Resolution column was updated as follows:
8 // eta=-3.5 - -2.5: sigma_p/p ~ 0.1%×p+2.0% -> sigma_p/p ~ 0.1%×p ⊕ 0.5%
9 // eta=-2.5 - -2.0: sigma_p/p ~ 0.1%×p+1.0% -> sigma_p/p ~ 0.1%×p ⊕ 0.5%
10 // eta=-2.0 - -1.0: sigma_p/p ~ 0.1%×p+1.0% -> sigma_p/p ~ 0.05%×p ⊕ 0.5%
11 // The abstract, reference files, and note sections of these fields have been updated accordingly.
12 
13 // Important Notes:
14 // - The implementation of the original handbook matrix in SmearHandBook_1_2.cxx
15 // took some liberties and added constant terms and other specifications where
16 // they were/are missing in the matrix.
17 // The implementation here explicitly does not do so, and aims to be completely faithful
18 // to the configuration available online.
19 // - Where ranges are given, the more conservative number is chosen.
20 // - Without available specifications, angular resolution is assumed to be perfect.
21 // -
22 
25 #include "eicsmear/smear/Device.h"
27 #include "eicsmear/smear/Smearer.h"
30 #include <eicsmear/smear/Smear.h>
32 #include "Math/Vector4D.h"
33 
34 // declare static --> local to this file, won't clash with others
35 static double ThetaFromEta( const double eta );
36 
38  gSystem->Load("libeicsmear");
39 
40  // Create the detector object to hold all devices
41  Smear::Detector det;
42 
43  // The framework provides implementations of three kinematic calculation methods
44  // from smeared values
45  // NM - "Null method" uses the scattered lepton.
46  // DA - Double Angle method
47  // JB - Jacquet-Blondel method
48  // Important Notes:
49  // - All methods rely on measured energy and momentum components (lepton for NM, hadrons for DA, JB).
50  // In order to rely on these methods, you therefore _need_ to cover the relevant
51  // regions with smearers for momentum, angles and energy.
52  // - This is exacerbated by the fact that in the current implementation a smearing of e.g. P
53  // may fool the framework into assuming theta is measured to be the initialization value 0,
54  // leading to nan or inf or otherwise wrong calculations.
55  // NM catches P=0 and replaces it in calculations with E,
56  // but JB and DA either don't work at all or report nonsenical values.
57  // - It may be advantageous to use a P measurement in place of E in a more general case.
58  // In the future, we plan to change to a weighted mean approach.
59  // The summary of the above is that the user should be mindful of the limitations and assumptions in
60  // the calculation of smeared kinematics. Sophisticated calculations are best redone in user code
61  // from the smeared particles directly.
62  det.SetEventKinematicsCalculator("NM DA JB");
63 
64  // IMPORTANT: There are two traps (will be addressed in future releases):
65  // 1) If you smear E but don't provide phi, theta smearers, those values will be
66  // set to 0, not to a fault value and not to the truth level
67  // 2) If you do provide such a smearer, pt and pz will be changed
68  // by a consistency enforcer in Detector::Smear()
69 
70 
71  // Perfect phi and theta for all particles
72  // ---------------------------------------
73  // total coverage of the handbook for tracker and hcal is -3.5 < eta < 3.5
74  Smear::Acceptance::Zone AngleZoneHadronic(ThetaFromEta ( 3.5 ),ThetaFromEta ( -3.5 ));
75  Smear::Device SmearThetaHadronic(Smear::kTheta, "0.0");
76  SmearThetaHadronic.Accept.AddZone(AngleZoneHadronic);
77  SmearThetaHadronic.Accept.SetGenre(Smear::kHadronic);
78  det.AddDevice(SmearThetaHadronic);
79 
80  Smear::Device SmearPhiHadronic(Smear::kPhi, "0.0");
81  SmearPhiHadronic.Accept.AddZone(AngleZoneHadronic);
82  SmearPhiHadronic.Accept.SetGenre(Smear::kHadronic);
83  det.AddDevice(SmearPhiHadronic);
84 
85  // muons are neither hadrons nor electromgnetic
86  Smear::Acceptance::Zone AngleZoneMuon(ThetaFromEta ( 3.5 ),ThetaFromEta ( -3.5 ));
87  Smear::Device SmearThetaMuon(Smear::kTheta, "0.0");
88  SmearThetaMuon.Accept.AddZone(AngleZoneMuon);
89  SmearThetaMuon.Accept.AddParticle(13);
90  SmearThetaMuon.Accept.AddParticle(-13);
91  det.AddDevice(SmearThetaMuon);
92 
93  Smear::Device SmearPhiMuon(Smear::kPhi, "0.0");
94  SmearPhiMuon.Accept.AddZone(AngleZoneMuon);
95  SmearPhiMuon.Accept.AddParticle(13);
96  SmearPhiMuon.Accept.AddParticle(-13);
97  det.AddDevice(SmearPhiMuon);
98 
99  // emcal stretches to -4.5 < eta < 4.5
100  Smear::Acceptance::Zone AngleZoneEmcal(ThetaFromEta ( 4.5 ),ThetaFromEta ( -4.5 ));
101  Smear::Device SmearThetaEmcal(Smear::kTheta, "0.0");
102  SmearThetaEmcal.Accept.AddZone(AngleZoneEmcal);
103  SmearThetaEmcal.Accept.SetGenre(Smear::kElectromagnetic);
104  det.AddDevice(SmearThetaEmcal);
105 
106  Smear::Device SmearPhiEmcal(Smear::kPhi, "0.0");
107  SmearPhiEmcal.Accept.AddZone(AngleZoneEmcal);
108  SmearPhiEmcal.Accept.SetGenre(Smear::kElectromagnetic);
109  det.AddDevice(SmearPhiEmcal);
110 
111  // Tracking
112  // --------
113  // Note: Smear::kCharged checks pdg charge, so includes muons (good)
114  // eta = -3.5 -- -2.0
115  // sigma_p/p ~ 0.1% p+0.5%
116  Smear::Acceptance::Zone TrackBack1Zone(ThetaFromEta ( -2.5 ),ThetaFromEta ( -3.5 ));
117  Smear::Device TrackBack1P(Smear::kP, "sqrt( pow ( 0.001*P*P, 2) + pow ( 0.005*P, 2) )");
118  TrackBack1P.Accept.AddZone(TrackBack1Zone);
119  TrackBack1P.Accept.SetCharge(Smear::kCharged);
120  det.AddDevice(TrackBack1P);
121 
122  // eta = -2.0 -- -1
123  // sigma_p/p ~ 0.05% p+ 0.5%
124  Smear::Acceptance::Zone TrackBack2Zone(ThetaFromEta ( -1 ),ThetaFromEta ( -2.5 ));
125  Smear::Device TrackBack2P(Smear::kP, "sqrt( pow ( 0.0005*P*P, 2) + pow ( 0.005*P, 2) )");
126  TrackBack2P.Accept.AddZone(TrackBack2Zone);
127  TrackBack2P.Accept.SetCharge(Smear::kCharged);
128  det.AddDevice(TrackBack2P);
129 
130  // eta = -1 -- +1
131  // sigma_p/p ~ 0.05% p+0.5%
132  Smear::Acceptance::Zone TrackBarrelZone(ThetaFromEta ( 1 ),ThetaFromEta ( -1 ));
133  Smear::Device TrackBarrelP(Smear::kP, "sqrt( pow ( 0.0005*P*P, 2) + pow ( 0.005*P, 2) )");
134  TrackBarrelP.Accept.AddZone(TrackBarrelZone);
135  TrackBarrelP.Accept.SetCharge(Smear::kCharged);
136  det.AddDevice(TrackBarrelP);
137 
138  // eta = 1 -- 2.5
139  // sigma_p/p ~ 0.05% p+1.0%
140  Smear::Acceptance::Zone TrackFwd2Zone(ThetaFromEta ( 2.5 ),ThetaFromEta ( 1 ));
141  Smear::Device TrackFwd2P(Smear::kP, "sqrt( pow ( 0.0005*P*P, 2) + pow ( 0.01*P, 2) )");
142  TrackFwd2P.Accept.AddZone(TrackFwd2Zone);
143  TrackFwd2P.Accept.SetCharge(Smear::kCharged);
144  det.AddDevice(TrackFwd2P);
145 
146  // eta = 2.5 -- 3.5
147  // sigma_p/p ~ 0.1% p+2.0%
148  Smear::Acceptance::Zone TrackFwd1Zone(ThetaFromEta ( 3.5 ),ThetaFromEta ( 2.5 ));
149  Smear::Device TrackFwd1P(Smear::kP, "sqrt( pow ( 0.001*P*P, 2) + pow ( 0.02*P, 2) )");
150  TrackFwd1P.Accept.AddZone(TrackFwd1Zone);
151  TrackFwd1P.Accept.SetCharge(Smear::kCharged);
152  det.AddDevice(TrackFwd1P);
153 
154  // EM Calorimeters
155  // ---------------
156  // Note: Smear::kElectromagnetic == gamma + e. Does not include muons (good)
157 
158  // Calorimeter resolution usually given as sigma_E/E = const% + stocastic%/Sqrt{E}
159  // EIC Smear needs absolute sigma: sigma_E = Sqrt{const*const*E*E + stoc*stoc*E}
160 
161  // Back
162  // eta = -4.5 -- -2
163  // stoch. = 2%
164  Smear::Acceptance::Zone EmcalBackZone(ThetaFromEta ( -2 ),ThetaFromEta ( -4.5 ));
165  Smear::Device EmcalBack(Smear::kE, "sqrt( pow ( 0.0*E,2 ) + pow( 0.02,2)*E)");
166  EmcalBack.Accept.AddZone(EmcalBackZone);
168  det.AddDevice(EmcalBack);
169 
170  // MidBack
171  // eta = -2 -- -1
172  // stoch. = 7%
173  Smear::Acceptance::Zone EmcalMidBackZone(ThetaFromEta ( -1 ),ThetaFromEta ( -2 ));
174  Smear::Device EmcalMidBack(Smear::kE, "sqrt( pow ( 0.0*E,2 ) + pow( 0.07,2)*E)");
175  EmcalMidBack.Accept.AddZone(EmcalMidBackZone);
177  det.AddDevice(EmcalMidBack);
178 
179  // Forward
180  // eta = -1 -- 4.5
181  // stoch. = 10-12%, use 12%
182  Smear::Acceptance::Zone EmcalFwdZone(ThetaFromEta ( 4.5 ),ThetaFromEta ( -1 ));
183  Smear::Device EmcalFwd(Smear::kE, "sqrt( pow ( 0.0*E,2 ) + pow( 0.12,2)*E)");
184  EmcalFwd.Accept.AddZone(EmcalFwdZone);
186  det.AddDevice(EmcalFwd);
187 
188  // Could turn on perfect PID
189  // Make sure to not cover more than is covered by the other detectors.
190  // Using the smallest region here, but we could add a second one for
191  // the extended EmCal range
192  // Smear::Acceptance::Zone acceptpid(ThetaFromEta(3.5),ThetaFromEta(-3.5));
193  // Smear::PerfectID pid;
194  // pid.Accept.AddZone(acceptpid);
195  // det.AddDevice( pid );
196 
197  // Hadronic Calorimeters
198  // ----------------------
199  // Note: kHadronic == |pdg|>110.
200 
201  // Back
202  // eta = -3.5 -- -1
203  // stoch. = 50%
204  Smear::Acceptance::Zone HcalBackZone(ThetaFromEta ( -1 ),ThetaFromEta ( -3.5 ));
205  Smear::Device HcalBack(Smear::kE, "sqrt(pow( 0.0*E, 2) + pow ( 0.5,2) *E)");
206  HcalBack.Accept.AddZone(HcalBackZone);
207  HcalBack.Accept.SetGenre(Smear::kHadronic);
208  det.AddDevice(HcalBack);
209 
210  // Barrel
211  // eta = -1 -- 1
212  // The matrix has nothing. As examples, one could turn to
213  // ~CMS
214  // Smear::Device HcalBarrel(Smear::kE, "sqrt( pow( 0.07*E, 2) + pow( 0.85, 2)*E)");
215  // ~Zeus
216  // Smear::Device HcalBarrel(Smear::kE, "sqrt( pow( 0.02*E, 2) + pow( 0.35,2) *E)");
217 
218  // Smear::Acceptance::Zone HcalBarrelZone(ThetaFromEta ( 1 ),ThetaFromEta ( -1 ));
219  // HcalBarrel.Accept.AddZone(HcalBarrelZone);
220  // HcalBarrel.Accept.SetGenre(Smear::kHadronic);
221  // det.AddDevice(HcalBarrel);
222 
223  // Forward
224  // eta = 1 -- 3.5
225  // stoch. = 50%
226  Smear::Acceptance::Zone HcalFwdZone(ThetaFromEta ( 3.5 ),ThetaFromEta ( 1 ));
227  Smear::Device HcalFwd(Smear::kE, "sqrt(pow( 0.0*E, 2) + pow ( 0.5,2) *E)");
228  HcalFwd.Accept.AddZone(HcalFwdZone);
230  det.AddDevice(HcalFwd);
231 
232  // Not covered:
233  // Tracker material budget X/X0 <~5%
234  // Low-Q^2 tagger: -6.9<eta<-5.8: Delta_theta/theta < 1.5%; 10^-6 < Q2 < 10^-2 GeV2
235  // Proton spectrometer: eta>6.2: sigma_intrinsic(|t|)/|t| < 1%; Acceptance: 0.2 < pT < 1.2 GeV/c
236  // Barrel vertexing: sigma_xyz ~ 20 microns, d0(z) ~ d0(r phi) ~ (20 microns)/(pT [GeV]) + 5 microns
237  // Central muon detection
238 
239  return det;
240 }
241 
242 // -------------------------------------------------------------------
243 double ThetaFromEta( const double eta ) {
244  if ( !std::isnan(eta) && !std::isinf(eta) ) {
245  return 2.0 * atan( exp( -eta ));
246  }
247  throw std::runtime_error("ThetaFromEta called with NaN or Inf");
248  return -1;
249 }