EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SmearCore_0_1_B3T.cxx
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file SmearCore_0_1_B3T.cxx
1 // Based on
2 // https://indico.bnl.gov/event/7913/contributions/41704/attachments/30564/47972/200924_Parametrizations.pdf
3 // https://indico.bnl.gov/event/11053/contributions/46969/attachments/33324/53540/core.pdf
4 
5 // From March 29, 2021
6 //
7 // Tracking assumes a 3T field
8 //
9 // Important Notes:
10 // - Where ranges are given, the more conservative number is chosen.
11 // - Without available specifications, angular resolution is assumed to be perfect.
12 // - Momentum and energy acceptance specifications are NOT implemented
13 // -- It is not a priori clear whether cuts should apply to truth or smeared value
14 // -- A "looper" may not reach the detector.
15 // -- On the other hand, a calorimetry deposit may fluctuate above threshold
16 // - PID for pi/K/p is implemented with perfect PID in the acceptance (and momentum range)
17 // - Electron PID is not implemented. Very high purity is important and not handled well with the above approach
18 
21 #include "eicsmear/smear/Device.h"
23 #include "eicsmear/smear/Smearer.h"
26 #include <eicsmear/smear/Smear.h>
28 #include "Math/Vector4D.h"
29 
30 // declare static --> local to this file, won't clash with others
31 static double ThetaFromEta( const double eta );
32 
34  gSystem->Load("libeicsmear");
35 
36  // Create the detector object to hold all devices
37  Smear::Detector det;
38 
39  // The framework provides implementations of three kinematic calculation methods
40  // from smeared values
41  // NM - "Null method" uses the scattered lepton.
42  // DA - Double Angle method
43  // JB - Jacquet-Blondel method
44  // Users should be mindful of the limitations and assumptions in
45  // the calculation of smeared kinematics. Sophisticated calculations are best redone in user code
46  // from the smeared particles directly.
47  det.SetEventKinematicsCalculator("NM DA JB");
48 
49  // Perfect phi and theta for all particles
50  // ---------------------------------------
51  // total coverage for tracker, ecal, and hcal is -4.0 < eta < 4.0
52  Smear::Acceptance::Zone AngleZoneCommon(ThetaFromEta ( 4.0 ),ThetaFromEta ( -4.0 ));
53  Smear::Device SmearThetaCommon(Smear::kTheta, "0.0");
54  SmearThetaCommon.Accept.AddZone(AngleZoneCommon);
55  SmearThetaCommon.Accept.SetGenre(Smear::kAll);
56  det.AddDevice(SmearThetaCommon);
57 
58  Smear::Device SmearPhiCommon(Smear::kPhi, "0.0");
59  SmearPhiCommon.Accept.AddZone(AngleZoneCommon);
60  SmearPhiCommon.Accept.SetGenre(Smear::kAll);
61  det.AddDevice(SmearPhiCommon);
62 
63  // Tracking (B = 3 T)
64  // --------
65  // Note: Smear::kCharged checks pdg charge, so includes muons (good)
66 
67  // |eta| = 0 -- 0.5
68  // sigma_p/p ~ 0.018 % p + 0.369 %
69  Smear::Device TrackPos1(Smear::kP, "sqrt( pow ( 0.018 * 0.01 *P*P, 2) + pow ( 0.369 * 0.01 *P, 2) )");
70  TrackPos1.Accept.SetCharge(Smear::kCharged);
71  Smear::Device TrackNeg1 = TrackPos1;
72  Smear::Acceptance::Zone TrackZonePos1(ThetaFromEta ( 0.5 ), ThetaFromEta ( 0.0 ));
73  Smear::Acceptance::Zone TrackZoneNeg1(ThetaFromEta ( 0.0 ), ThetaFromEta ( -0.5 ));
74  TrackPos1.Accept.AddZone(TrackZonePos1);
75  TrackNeg1.Accept.AddZone(TrackZoneNeg1);
76  det.AddDevice(TrackPos1);
77  det.AddDevice(TrackNeg1);
78 
79  // |eta| = 0.5 -- 1
80  // sigma_p/p ~ 0.016 % p + 0.428 %
81  Smear::Device TrackPos2(Smear::kP, "sqrt( pow ( 0.016 * 0.01 *P*P, 2) + pow ( 0.428 * 0.01 *P, 2) )");
82  TrackPos2.Accept.SetCharge(Smear::kCharged);
83  Smear::Device TrackNeg2 = TrackPos2;
84  Smear::Acceptance::Zone TrackZonePos2(ThetaFromEta ( 1.0 ), ThetaFromEta ( 0.5 ));
85  Smear::Acceptance::Zone TrackZoneNeg2(ThetaFromEta ( -0.5 ), ThetaFromEta ( -1.0 ));
86  TrackPos2.Accept.AddZone(TrackZonePos2);
87  TrackNeg2.Accept.AddZone(TrackZoneNeg2);
88  det.AddDevice(TrackPos2);
89  det.AddDevice(TrackNeg2);
90 
91  // |eta| = 1 -- 1.5
92  // sigma_p/p ~ 0.016 % p + 0.427 %
93  Smear::Device TrackPos3(Smear::kP, "sqrt( pow ( 0.016 * 0.01 *P*P, 2) + pow ( 0.427 * 0.01 *P, 2) )");
94  TrackPos3.Accept.SetCharge(Smear::kCharged);
95  Smear::Device TrackNeg3 = TrackPos3;
96  Smear::Acceptance::Zone TrackZonePos3(ThetaFromEta ( 1.5 ), ThetaFromEta ( 1.0 ));
97  Smear::Acceptance::Zone TrackZoneNeg3(ThetaFromEta ( -1.0 ), ThetaFromEta ( -1.5 ));
98  TrackPos3.Accept.AddZone(TrackZonePos3);
99  TrackNeg3.Accept.AddZone(TrackZoneNeg3);
100  det.AddDevice(TrackPos3);
101  det.AddDevice(TrackNeg3);
102 
103 
104  // |eta| = 1.5 -- 2
105  // sigma_p/p ~ 0.012 % p + 0.462 %
106  Smear::Device TrackPos4(Smear::kP, "sqrt( pow ( 0.012 * 0.01 *P*P, 2) + pow ( 0.462 * 0.01 *P, 2) )");
107  TrackPos4.Accept.SetCharge(Smear::kCharged);
108  Smear::Device TrackNeg4 = TrackPos4;
109  Smear::Acceptance::Zone TrackZonePos4(ThetaFromEta ( 2.0 ), ThetaFromEta ( 1.5 ));
110  Smear::Acceptance::Zone TrackZoneNeg4(ThetaFromEta ( -1.5 ), ThetaFromEta ( -2.0 ));
111  TrackPos4.Accept.AddZone(TrackZonePos4);
112  TrackNeg4.Accept.AddZone(TrackZoneNeg4);
113  det.AddDevice(TrackPos4);
114  det.AddDevice(TrackNeg4);
115 
116  // |eta| = 2 -- 2.5
117  // sigma_p/p ~ 0.018 % p + 0.719 %
118  Smear::Device TrackPos5(Smear::kP, "sqrt( pow ( 0.018 * 0.01 *P*P, 2) + pow ( 0.719 * 0.01 *P, 2) )");
119  TrackPos5.Accept.SetCharge(Smear::kCharged);
120  Smear::Device TrackNeg5 = TrackPos5;
121  Smear::Acceptance::Zone TrackZonePos5(ThetaFromEta ( 2.5 ), ThetaFromEta ( 2.0 ));
122  Smear::Acceptance::Zone TrackZoneNeg5(ThetaFromEta ( -2.0 ), ThetaFromEta ( -2.5 ));
123  TrackPos5.Accept.AddZone(TrackZonePos5);
124  TrackNeg5.Accept.AddZone(TrackZoneNeg5);
125  det.AddDevice(TrackPos5);
126  det.AddDevice(TrackNeg5);
127 
128  // |eta| = 2.5 -- 3
129  // sigma_p/p ~ 0.039 % p + 1.336 %
130  Smear::Device TrackPos6(Smear::kP, "sqrt( pow ( 0.039 * 0.01 *P*P, 2) + pow ( 1.336 * 0.01 *P, 2) )");
131  TrackPos6.Accept.SetCharge(Smear::kCharged);
132  Smear::Device TrackNeg6 = TrackPos6;
133  Smear::Acceptance::Zone TrackZonePos6(ThetaFromEta ( 3.0 ), ThetaFromEta ( 2.5 ));
134  Smear::Acceptance::Zone TrackZoneNeg6(ThetaFromEta ( -2.5 ), ThetaFromEta ( -3.0 ));
135  TrackPos6.Accept.AddZone(TrackZonePos6);
136  TrackNeg6.Accept.AddZone(TrackZoneNeg6);
137  det.AddDevice(TrackPos6);
138  det.AddDevice(TrackNeg6);
139 
140 
141  // |eta| = 3 -- 3.5
142  // sigma_p/p ~ 0.103 % p + 2.428 %
143  Smear::Device TrackPos7(Smear::kP, "sqrt( pow ( 0.103 * 0.01 *P*P, 2) + pow ( 2.428 * 0.01 *P, 2) )");
144  TrackPos7.Accept.SetCharge(Smear::kCharged);
145  Smear::Device TrackNeg7 = TrackPos7;
146  Smear::Acceptance::Zone TrackZonePos7(ThetaFromEta ( 3.5 ), ThetaFromEta ( 3.0 ));
147  Smear::Acceptance::Zone TrackZoneNeg7(ThetaFromEta ( -3.0 ), ThetaFromEta ( -3.5 ));
148  TrackPos7.Accept.AddZone(TrackZonePos7);
149  TrackNeg7.Accept.AddZone(TrackZoneNeg7);
150  det.AddDevice(TrackPos7);
151  det.AddDevice(TrackNeg7);
152 
153  // |eta| = 3.5 -- 4.0
154  // sigma_p/p ~ 0.295 % p + 4.552 %
155  Smear::Device TrackPos8(Smear::kP, "sqrt( pow ( 0.295 * 0.01 *P*P, 2) + pow ( 4.552 * 0.01 *P, 2) )");
156  TrackPos8.Accept.SetCharge(Smear::kCharged);
157  Smear::Device TrackNeg8 = TrackPos8;
158  Smear::Acceptance::Zone TrackZonePos8(ThetaFromEta ( 4.0 ), ThetaFromEta ( 3.5 ));
159  Smear::Acceptance::Zone TrackZoneNeg8(ThetaFromEta ( -3.5 ), ThetaFromEta ( -4.0 ));
160  TrackPos8.Accept.AddZone(TrackZonePos8);
161  TrackNeg8.Accept.AddZone(TrackZoneNeg8);
162  det.AddDevice(TrackPos8);
163  det.AddDevice(TrackNeg8);
164 
165 
166  // PID
167  // ---
168  // Perfect pi/K/P PID everywhere for now
169  // Make sure to not cover more than is covered by the other detectors.
170  // No minimum momentum is used.
171  // Accept charged hadrons (excludes e, mu)
172 
173  // p < 10 GeV
175  0., TMath::TwoPi(), // phi
176  0., TMath::Infinity(), // E
177  0., 10 ); // p
178  Smear::PerfectID Pid;
179  Pid.Accept.AddZone(PidZone);
182  det.AddDevice( Pid );
183 
184  // EM Calorimeters
185  // ---------------
186  // Note: Smear::kElectromagnetic == gamma + e. Does not include muons (good)
187  // Calorimeter resolution usually given as sigma_E/E = A% / E + B%/Sqrt{E} + C%
188  // EIC Smear needs absolute sigma: sigma_E = Sqrt{A*A + B*B*E + C*C*E*E}
189 
190  // E> 20 (50) MeV not used because it suppresses smeared-up particles
191 
192  // Inner Back
193  // eta = -3.5 -- -2.0
194  // 1%/E + 2.5%/sqrtE + 1%
195  // A B C
196  Smear::Acceptance::Zone EmcalInnerBackZone(ThetaFromEta ( -2.0 ),ThetaFromEta ( -3.5 ));
197  Smear::Device EmcalInnerBack(Smear::kE, "sqrt( pow ( 0.01,2 ) + pow( 0.025,2)*E + pow ( 0.01*E,2 ) )");
198  EmcalInnerBack.Accept.AddZone(EmcalInnerBackZone);
199  EmcalInnerBack.Accept.SetGenre(Smear::kElectromagnetic);
200  det.AddDevice(EmcalInnerBack);
201 
202  // Outer Back / Barrel
203  // eta = -2.0 -- 0.0
204  // 2%/E + 4%/sqrtE + 2%
205  // A B C
206  Smear::Acceptance::Zone EmcalOuterBackZone(ThetaFromEta ( 0.0 ),ThetaFromEta ( -2.0 ));
207  Smear::Device EmcalOuterBack(Smear::kE, "sqrt( pow ( 0.02,2 ) + pow( 0.04,2)*E + pow ( 0.02*E,2 ) )");
208  EmcalOuterBack.Accept.AddZone(EmcalOuterBackZone);
209  EmcalOuterBack.Accept.SetGenre(Smear::kElectromagnetic);
210  det.AddDevice(EmcalOuterBack);
211 
212 
213  // Forward barrel - assume Matrix specs (waiting for Craig Woody's talk)
214  // eta = 0 -- 1
215  // E > 100 MeV (50 MeV if higher resolution)
216  // not used because it suppresses smeared-up particles
217  // 2%/EāŠ•(12-14)%/āˆšEāŠ•(2-3)% for 30 cm space
218  // choosing
219  // 2%/E + 14%/sqrtE + 3%
220  // A B C
221  Smear::Acceptance::Zone EmcalForwardBarrelZone(ThetaFromEta ( 1 ),ThetaFromEta ( 0 ));
222  Smear::Device EmcalForwardBarrel(Smear::kE, "sqrt( pow ( 0.02,2 ) + pow( 0.14,2)*E + pow ( 0.03*E,2 ) )");
223  EmcalForwardBarrel.Accept.AddZone(EmcalForwardBarrelZone);
224  EmcalForwardBarrel.Accept.SetGenre(Smear::kElectromagnetic);
225  det.AddDevice(EmcalForwardBarrel);
226 
227  // Forward outer - assume Matrix specs (waiting for Craig Woody's talk)
228  // eta = 1 -- 2
229  // E > 50 MeV not used because it suppresses smeared-up particles
230  // "2%/E + (4*-12)%/sqrtE + 2% Upper limit achievable with 40cm space
231  // *Better resolution requires ~65 cm space allocated"
232  // choosing
233  // 2%/E + 12%/sqrtE + 2%
234  // A B C
235  Smear::Acceptance::Zone EmcalFwdOuterZone(ThetaFromEta ( 2 ),ThetaFromEta ( 1 )); // E
236  Smear::Device EmcalFwdOuter(Smear::kE, "sqrt( pow ( 0.02,2 ) + pow( 0.12,2)*E + pow ( 0.02*E,2 ) )");
237  EmcalFwdOuter.Accept.AddZone(EmcalFwdOuterZone);
238  EmcalFwdOuter.Accept.SetGenre(Smear::kElectromagnetic);
239  det.AddDevice(EmcalFwdOuter);
240 
241  // > Shashlyk, Pb/Sc 5.5 x5.5, 8% stochastic, 2% constant.
242 
243  // Forward inner - Shashlyk guess
244  // eta = 2 -- 3.5
245  // E > 50 MeV not used because it suppresses smeared-up particles
246  // Optimistic Shashlyk
247  // 2%/E + 8%/sqrtE + 2%
248  // A B C
249  Smear::Acceptance::Zone EmcalFwdInnerZone(ThetaFromEta ( 3.5 ),ThetaFromEta ( 2 )); // E
250  Smear::Device EmcalFwdInner(Smear::kE, "sqrt( pow ( 0.02,2 ) + pow( 0.8,2)*E + pow ( 0.02*E,2 ) )");
251  EmcalFwdInner.Accept.AddZone(EmcalFwdInnerZone);
252  EmcalFwdInner.Accept.SetGenre(Smear::kElectromagnetic);
253  det.AddDevice(EmcalFwdInner);
254 
255 
256  // Hadronic Calorimeters
257  // Assume marix specs (waiting for Oleg Tsai's talk)
258  // Except, aspire to 35 % / sqrt(E) + 2% forward
259  // ----------------------
260  // Note: kHadronic == |pdg|>110.
261 
262  // Back
263  // eta = -3.5 -- -1
264  // E>500 MeV not used because it suppresses smeared-up particles
265  // (Better resolution required more space and R&D)
266  // stoch. = 50%, const = 10%
267  Smear::Acceptance::Zone HcalBackZone(ThetaFromEta ( -1 ),ThetaFromEta ( -3.5 ) );
268  Smear::Device HcalBack(Smear::kE, "sqrt(pow( 0.1*E, 2) + pow ( 0.5,2) *E)");
269  HcalBack.Accept.AddZone(HcalBackZone);
270  HcalBack.Accept.SetGenre(Smear::kHadronic);
271  det.AddDevice(HcalBack);
272 
273  // Barrel
274  // eta = -1 -- 1
275  // E>500 MeV not used because it suppresses smeared-up particles
276  // stoch. = 100%, const = 10%
277  Smear::Acceptance::Zone HcalBarrelZone(ThetaFromEta ( 1 ),ThetaFromEta ( -1 ) ); // E
278  Smear::Device HcalBarrel(Smear::kE, "sqrt( pow( 0.1*E, 2) + pow( 1.0, 2)*E)");
279  HcalBarrel.Accept.AddZone(HcalBarrelZone);
280  HcalBarrel.Accept.SetGenre(Smear::kHadronic);
281  det.AddDevice(HcalBarrel);
282 
283  // Forward
284  // eta = 1 -- 3.5
285  // E>500 MeV not used because it suppresses smeared-up particles
286  // stoch. = 35%, const = 2% (aspirational goal)
287  Smear::Acceptance::Zone HcalFwdZone(ThetaFromEta ( 3.5 ),ThetaFromEta ( 1 ));
288  Smear::Device HcalFwd(Smear::kE, "sqrt(pow( 0.02*E, 2) + pow ( 0.35,2) *E)");
289  HcalFwd.Accept.AddZone(HcalFwdZone);
291  det.AddDevice(HcalFwd);
292 
293  return det;
294 }
295 
296 // -------------------------------------------------------------------
297 double ThetaFromEta( const double eta ) {
298  if ( !std::isnan(eta) && !std::isinf(eta) ) {
299  return 2.0 * atan( exp( -eta ));
300  }
301  throw std::runtime_error("ThetaFromEta called with NaN or Inf");
302  return -1;
303 }