1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
|
#ifndef FastSimulation_CaloHitMakers_EcalHitMaker_h
#define FastSimulation_CaloHitMakers_EcalHitMaker_h
#include "Geometry/CaloTopology/interface/CaloDirection.h"
//#include "FastSimulation/Event/interface/FSimTrack.h"
#include "FastSimulation/CaloHitMakers/interface/CaloHitMaker.h"
#include "FastSimulation/CaloGeometryTools/interface/CaloPoint.h"
#include "FastSimulation/CaloGeometryTools/interface/CaloSegment.h"
#include "FastSimulation/CaloGeometryTools/interface/CrystalPad.h"
#include "FastSimulation/CaloGeometryTools/interface/Crystal.h"
#include "FastSimulation/Utilities/interface/FamosDebug.h"
//#include <boost/cstdint.hpp>
#include <vector>
class CaloGeometryHelper;
class CrystalWindowMap;
class Histos;
class RandomEngineAndDistribution;
class FSimTrack;
class EcalHitMaker : public CaloHitMaker {
public:
typedef math::XYZVector XYZVector;
typedef math::XYZVector XYZPoint;
typedef math::XYZVector XYZNormal;
typedef ROOT::Math::Plane3D Plane3D;
EcalHitMaker(CaloGeometryHelper* calo,
const XYZPoint& ecalentrance,
const DetId& cell,
int onEcal,
unsigned size,
unsigned showertype,
const RandomEngineAndDistribution* engine);
~EcalHitMaker() override;
// This is not part of the constructor but it has to be called very early
void setTrackParameters(const XYZNormal& normal, double X0depthoffset, const FSimTrack& theTrack);
// The following methods are related to the path of the particle
// through the detector.
// Number of X0 "seen" by the track
// inline double totalX0() const {return totalX0_-X0depthoffset_;};
inline double totalX0() const { return totalX0_; };
/// Number of interaction length "seen" by the track
inline double totalL0() const { return totalL0_; };
/// get the offset (e.g the number of X0 after which the shower starts)
inline double x0DepthOffset() const { return X0depthoffset_; }
// total number of X0 in the PS (Layer1).
inline double ps1TotalX0() const { return X0PS1_; }
/// total number of X0 in the PS (Layer2).
inline double ps2TotalX0() const { return X0PS2_; }
// number of X0 between PS2 and EE
inline double ps2eeTotalX0() const { return X0PS2EE_; }
/// in the ECAL
inline double ecalTotalX0() const { return X0ECAL_; }
/// ECAL-HCAL transition
inline double ecalHcalGapTotalX0() const { return X0EHGAP_; }
/// in the HCAL
inline double hcalTotalX0() const { return X0HCAL_; }
/// total number of L0 in the PS (Layer1).
inline double ps1TotalL0() const { return L0PS1_; }
/// total number of L0 in the PS (Layer2).
inline double ps2TotalL0() const { return L0PS2_; }
// number of X0 between PS2 and EE
inline double ps2eeTotalL0() const { return L0PS2EE_; }
/// in the ECAL
inline double ecalTotalL0() const { return L0ECAL_; }
/// in the HCAL
inline double hcalTotalL0() const { return L0HCAL_; }
/// ECAL-HCAL transition
inline double ecalHcalGapTotalL0() const { return L0EHGAP_; }
/// retrieve the segments (the path in the crystal crossed by the extrapolation
/// of the track. Debugging only
inline const std::vector<CaloSegment>& getSegments() const { return segments_; };
// The following methods are EM showers specific
/// computes the crystals-plan intersection at depth (in X0 or L0 depending on the
///shower type)
/// if it is not possible to go at such a depth, the result is false
bool getPads(double depth, bool inCm = false);
inline double getX0back() const { return maxX0_; }
bool addHitDepth(double r, double phi, double depth = -1);
bool addHit(double r, double phi, unsigned layer = 0) override;
unsigned fastInsideCell(const CLHEP::Hep2Vector& point, double& sp, bool debug = false);
inline void setSpotEnergy(double e) override { spotEnergy = e; }
/// get the map of the stored hits. Triggers the calculation of the grid if it has
/// not been done.
const std::map<CaloHitID, float>& getHits() override;
/// To retrieve the track
const FSimTrack* getFSimTrack() const { return myTrack_; }
/// used in FamosHcalHitMaker
inline const XYZPoint& ecalEntrance() const { return EcalEntrance_; };
inline void setRadiusFactor(double r) { radiusCorrectionFactor_ = r; }
inline void setPulledPadSurvivalProbability(double val) { pulledPadProbability_ = val; };
inline void setCrackPadSurvivalProbability(double val) { crackPadProbability_ = val; };
// set preshower
inline void setPreshowerPresent(bool ps) { simulatePreshower_ = ps; };
/// for debugging
inline const std::vector<Crystal>& getCrystals() const { return regionOfInterest_; }
private:
// Computes the intersections of a track with the different calorimeters
void cellLine(std::vector<CaloPoint>& cp);
void preshowerCellLine(std::vector<CaloPoint>& cp) const;
void hcalCellLine(std::vector<CaloPoint>& cp) const;
void ecalCellLine(const XYZPoint&, const XYZPoint&, std::vector<CaloPoint>& cp);
void buildSegments(const std::vector<CaloPoint>& cp);
// retrieves the 7x7 crystals and builds the map of neighbours
void buildGeometry();
// depth-dependent geometry operations
void configureGeometry();
// project fPoint on the plane (origin,normal)
bool pulled(const XYZPoint& origin, const XYZNormal& normal, XYZPoint& fPoint) const;
// the numbering within the grid
void prepareCrystalNumberArray();
// find approximately the pad corresponding to (x,y)
void convertIntegerCoordinates(double x, double y, unsigned& ix, unsigned& iy) const;
// pads reorganization (to lift the gaps)
void reorganizePads();
// retrieves the coordinates of a corner belonging to the neighbour
typedef std::pair<CaloDirection, unsigned> neighbour;
CLHEP::Hep2Vector& correspondingEdge(neighbour& myneighbour, CaloDirection dir2);
// almost the same
bool diagonalEdge(unsigned myPad, CaloDirection dir, CLHEP::Hep2Vector& point);
// check if there is an unbalanced direction in the input vertor. If the result is true,
// the cooresponding directions are returned dir1+dir2=unb
bool unbalancedDirection(const std::vector<neighbour>& dirs, unsigned& unb, unsigned& dir1, unsigned& dir2);
// glue the pads together if there is no crack between them
void gapsLifting(std::vector<neighbour>& gaps, unsigned iq);
// creates a crack
void cracksPads(std::vector<neighbour>& cracks, unsigned iq);
private:
bool inside3D(const std::vector<XYZPoint>&, const XYZPoint& p) const;
// the numbering of the pads
std::vector<std::vector<unsigned> > myCrystalNumberArray_;
// The following quantities are related to the path of the track through the detector
double totalX0_;
double totalL0_;
double X0depthoffset_;
double X0PS1_;
double X0PS2_;
double X0PS2EE_;
double X0ECAL_;
double X0EHGAP_;
double X0HCAL_;
double L0PS1_;
double L0PS2_;
double L0PS2EE_;
double L0ECAL_;
double L0HCAL_;
double L0EHGAP_;
double maxX0_;
double rearleakage_;
double outsideWindowEnergy_;
// Grid construction
Crystal pivot_;
XYZPoint EcalEntrance_;
XYZNormal normal_;
int central_;
int onEcal_;
bool configuredGeometry_;
unsigned ncrystals_;
// size of the grid in the(x,y) plane
unsigned nx_, ny_;
double xmin_, xmax_, ymin_, ymax_;
std::vector<DetId> CellsWindow_;
std::vector<Crystal> regionOfInterest_;
std::vector<float> hits_;
// Validity of the pads. To be valid, the intersection of the crytal with the plane should have 4 corners
std::vector<bool> validPads_;
// Get the index of the crystal (in hits_ or regionOfInterest_) when its CellID is known
// Needed because the navigation uses DetIds.
std::map<DetId, unsigned> DetIdMap_;
CrystalWindowMap* myCrystalWindowMap_;
// First segment in ECAL
int ecalFirstSegment_;
// Properties of the crystal window
unsigned etasize_;
unsigned phisize_;
// is the grid complete ?
bool truncatedGrid_;
// shower simulation quantities
// This one is the shower enlargment wrt Grindhammer
double radiusCorrectionFactor_;
// moliere radius * radiuscorrectionfactor OR interactionlength
double radiusFactor_;
// is it necessary to trigger the detailed simulation of the shower tail ?
bool detailedShowerTail_;
// current depth
double currentdepth_;
// magnetic field correction factor
double bfactor_;
// simulate preshower
bool simulatePreshower_;
// pads-depth specific quantities
unsigned ncrackpadsatdepth_;
unsigned npadsatdepth_;
Plane3D plan_;
// spot survival probability for a pulled pad - corresponding to the front face of a crystal
// on the plan located in front of the crystal - Front leaking
double pulledPadProbability_;
// spot survival probability for the craks
double crackPadProbability_;
// size of the grid in the plane
double sizex_, sizey_;
// int fsimtrack_;
const FSimTrack* myTrack_;
// vector of the intersection of the track with the dectectors (PS,ECAL,HCAL)
std::vector<CaloPoint> intersections_;
// segments obtained from the intersections
std::vector<CaloSegment> segments_;
// should the pads be reorganized (most of the time YES! )
bool doreorg_;
// the geometrical objects
std::vector<CrystalPad> padsatdepth_;
std::vector<CrystalPad> crackpadsatdepth_;
bool hitmaphasbeencalculated_;
// A local vector of corners, to avoid reserving, newing and mallocing
std::vector<CLHEP::Hep2Vector> mycorners;
std::vector<XYZPoint> corners;
const RandomEngineAndDistribution* random;
#ifdef FAMOSDEBUG
Histos* myHistos;
#endif
};
#endif
|