CMS 3D CMS Logo

HGCSD.cc
Go to the documentation of this file.
1 // File: HGCSD.cc
3 // Description: Sensitive Detector class for Combined Forward Calorimeter
5 
7 
16 #include "G4LogicalVolumeStore.hh"
17 #include "G4LogicalVolume.hh"
18 #include "G4Step.hh"
19 #include "G4Track.hh"
20 #include "G4ParticleTable.hh"
21 #include "G4VProcess.hh"
22 #include "G4Trap.hh"
23 
24 #include <fstream>
25 #include <iomanip>
26 #include <iostream>
27 #include <memory>
28 
29 //#define EDM_ML_DEBUG
30 
32  const HGCalTBDDDConstants* hgc,
33  const SensitiveDetectorCatalog& clg,
34  edm::ParameterSet const& p,
35  const SimTrackManager* manager)
36  : CaloSD(name,
37  clg,
38  p,
39  manager,
40  (float)(p.getParameter<edm::ParameterSet>("HGCSD").getParameter<double>("TimeSliceUnit")),
41  p.getParameter<edm::ParameterSet>("HGCSD").getParameter<bool>("IgnoreTrackID")),
42  hgcons_(hgc),
43  slopeMin_(0),
44  levelT_(99) {
45 #ifdef plotDebug
46  tree_ = nullptr;
47 #endif
48  numberingScheme_.reset(nullptr);
49  mouseBite_.reset(nullptr);
50 
51  edm::ParameterSet m_HGC = p.getParameter<edm::ParameterSet>("HGCSD");
52  eminHit_ = m_HGC.getParameter<double>("EminHit") * CLHEP::MeV;
53  storeAllG4Hits_ = m_HGC.getParameter<bool>("StoreAllG4Hits");
54  rejectMB_ = m_HGC.getParameter<bool>("RejectMouseBite");
55  waferRot_ = m_HGC.getParameter<bool>("RotatedWafer");
56  angles_ = m_HGC.getUntrackedParameter<std::vector<double>>("WaferAngles");
57  double waferSize = m_HGC.getUntrackedParameter<double>("WaferSize") * CLHEP::mm;
58  double mouseBite = m_HGC.getUntrackedParameter<double>("MouseBite") * CLHEP::mm;
59  mouseBiteCut_ = waferSize * tan(30.0 * CLHEP::deg) - mouseBite;
60  dd4hep_ = p.getParameter<bool>("g4GeometryDD4hepSource");
61 
62  if (storeAllG4Hits_) {
63  setUseMap(false);
65  }
66  //this is defined in the hgcsens.xml
67  G4String myName = name;
69  nameX_ = "HGCal";
70  if (myName.find("HitsEE") != std::string::npos) {
72  nameX_ = "HGCalEESensitive";
73  } else if (myName.find("HitsHEfront") != std::string::npos) {
75  nameX_ = "HGCalHESiliconSensitive";
76  } else if (myName.find("HitsHEback") != std::string::npos) {
78  nameX_ = "HGCalHEScintillatorSensitive";
79  }
80 
81 #ifdef EDM_ML_DEBUG
82  edm::LogVerbatim("HGCSim") << "**************************************************"
83  << "\n"
84  << "* *"
85  << "\n"
86  << "* Constructing a HGCSD with name " << name << "\n"
87  << "* *"
88  << "\n"
89  << "**************************************************";
90 #endif
91  edm::LogVerbatim("HGCSim") << "HGCSD:: Threshold for storing hits: " << eminHit << " for " << nameX_ << " subdet "
92  << myFwdSubdet_;
93  edm::LogVerbatim("HGCSim") << "Flag for storing individual Geant4 Hits " << storeAllG4Hits_;
94  edm::LogVerbatim("HGCSim") << "Reject MosueBite Flag: " << rejectMB_ << " Size of wafer " << waferSize
95  << " Mouse Bite " << mouseBite << ":" << mouseBiteCut_ << " along " << angles_.size()
96  << " axes";
97 }
98 
99 double HGCSD::getEnergyDeposit(const G4Step* aStep) {
100  double r = aStep->GetPreStepPoint()->GetPosition().perp();
101  double z = std::abs(aStep->GetPreStepPoint()->GetPosition().z());
102 
103 #ifdef EDM_ML_DEBUG
104  G4int parCode = aStep->GetTrack()->GetDefinition()->GetPDGEncoding();
105  G4LogicalVolume* lv = aStep->GetPreStepPoint()->GetPhysicalVolume()->GetLogicalVolume();
106  edm::LogVerbatim("HGCSim") << "HGCSD: Hit from standard path from " << lv->GetName() << " for Track "
107  << aStep->GetTrack()->GetTrackID() << " ("
108  << aStep->GetTrack()->GetDefinition()->GetParticleName() << ":" << parCode << ") R = " << r
109  << " Z = " << z << " slope = " << r / z << ":" << slopeMin_;
110 #endif
111 
112  // Apply fiductial volume
113  if (r < z * slopeMin_) {
114  return 0.0;
115  }
116 
117  double wt1 = getResponseWt(aStep->GetTrack());
118  double wt2 = aStep->GetTrack()->GetWeight();
119  double destep = wt1 * aStep->GetTotalEnergyDeposit();
120  if (wt2 > 0)
121  destep *= wt2;
122 
123 #ifdef plotDebug
124  const G4VTouchable* touch = aStep->GetPreStepPoint()->GetTouchable();
125  G4double tmptrackE = aStep->GetTrack()->GetKineticEnergy();
126  G4int parCodex = aStep->GetTrack()->GetDefinition()->GetPDGEncoding();
127  G4double angle = (aStep->GetTrack()->GetMomentumDirection().theta()) / CLHEP::deg;
128  G4int layer = ((touch->GetHistoryDepth() == levelT_) ? touch->GetReplicaNumber(0) : touch->GetReplicaNumber(2));
129  G4int ilayer = (layer - 1) / 3;
130  if (aStep->GetTotalEnergyDeposit() > 0) {
131  t_Layer_.emplace_back(ilayer);
132  t_Parcode_.emplace_back(parCodex);
133  t_dEStep1_.emplace_back(aStep->GetTotalEnergyDeposit());
134  t_dEStep2_.emplace_back(destep);
135  t_TrackE_.emplace_back(tmptrackE);
136  t_Angle_.emplace_back(angle);
137  }
138 #endif
139 
140  return destep;
141 }
142 
143 uint32_t HGCSD::setDetUnitId(const G4Step* aStep) {
144  const G4StepPoint* preStepPoint = aStep->GetPreStepPoint();
145  const G4VTouchable* touch = preStepPoint->GetTouchable();
146 
147  //determine the exact position in global coordinates in the mass geometry
148  G4ThreeVector hitPoint = preStepPoint->GetPosition();
149  float globalZ = touch->GetTranslation(0).z();
150  int iz(globalZ > 0 ? 1 : -1);
151 
152  //convert to local coordinates (=local to the current volume):
153  G4ThreeVector localpos = touch->GetHistory()->GetTopTransform().TransformPoint(hitPoint);
154 
155  //get the det unit id with
157 
158  int layer(-1), moduleLev(-1), module(-1), cell(-1);
159  if (touch->GetHistoryDepth() == levelT_) {
160  layer = touch->GetReplicaNumber(0);
161 #ifdef EDM_ML_DEBUG
162  edm::LogVerbatim("HGCSim") << "Depths: " << touch->GetHistoryDepth() << " name " << touch->GetVolume(0)->GetName()
163  << " layer:module:cell " << layer << ":" << moduleLev << ":" << module << ":" << cell;
164 #endif
165  } else {
166  layer = touch->GetReplicaNumber(2);
167  module = touch->GetReplicaNumber(1);
168  cell = touch->GetReplicaNumber(0);
169  moduleLev = 1;
170  }
171 #ifdef EDM_ML_DEBUG
172  const G4Material* mat = aStep->GetPreStepPoint()->GetMaterial();
173  edm::LogVerbatim("HGCSim") << "Depths: " << touch->GetHistoryDepth() << " name " << touch->GetVolume(0)->GetName()
174  << ":" << touch->GetReplicaNumber(0) << " " << touch->GetVolume(1)->GetName() << ":"
175  << touch->GetReplicaNumber(1) << " " << touch->GetVolume(2)->GetName() << ":"
176  << touch->GetReplicaNumber(2) << " layer:module:cell " << layer << ":" << moduleLev
177  << ":" << module << ":" << cell << " Material " << mat->GetName() << ":"
178  << mat->GetRadlen();
179  for (int k = 0; k < touch->GetHistoryDepth(); ++k)
180  edm::LogVerbatim("HGCSim") << "Level [" << k << "] " << touch->GetVolume(k)->GetName() << ":"
181  << touch->GetReplicaNumber(k);
182 #endif
183  // The following statement should be examined later before elimination
184  // VI: this is likely a check if media is vacuum - not needed
185  if (aStep->GetPreStepPoint()->GetMaterial()->GetRadlen() > 100000.)
186  return 0;
187 
188  uint32_t id = setDetUnitId(subdet, layer, module, cell, iz, localpos);
189  if (rejectMB_ && id != 0) {
190  int det, z, lay, wafer, type, ic;
191  HGCalTestNumbering::unpackHexagonIndex(id, det, z, lay, wafer, type, ic);
192 #ifdef EDM_ML_DEBUG
193  edm::LogVerbatim("HGCSim") << "ID " << std::hex << id << std::dec << " Input " << subdet << ":" << layer << ":"
194  << module << ":" << cell << ":" << iz << localpos.x() << ":" << localpos.y()
195  << " Decode " << det << ":" << z << ":" << lay << ":" << wafer << ":" << type << ":"
196  << ic;
197 #endif
198  G4ThreeVector local =
199  ((moduleLev >= 0) ? (touch->GetHistory()->GetTransform(moduleLev).TransformPoint(hitPoint)) : G4ThreeVector());
200  if (mouseBite_->exclude(local, z, layer, wafer, 0))
201  id = 0;
202  }
203  return id;
204 }
205 
206 void HGCSD::update(const BeginOfJob* job) {
207  if (hgcons_ != nullptr) {
210  levelT_ = hgcons_->levelTop();
211  if (dd4hep_)
212  ++levelT_;
213  numberingScheme_ = std::make_unique<HGCNumberingScheme>(*hgcons_, nameX_);
214  if (rejectMB_)
215  mouseBite_ = std::make_unique<HGCMouseBite>(*hgcons_, angles_, mouseBiteCut_, waferRot_);
216  } else {
217  edm::LogError("HGCSim") << "HGCSD : Cannot find HGCalTBDDDConstants for " << nameX_;
218  throw cms::Exception("Unknown", "HGCSD") << "Cannot find HGCalTBDDDConstants for " << nameX_ << "\n";
219  }
220 #ifdef EDM_ML_DEBUG
221  edm::LogVerbatim("HGCSim") << "HGCSD::Initialized with mode " << geom_mode_ << " Slope cut " << slopeMin_
222  << " top Level " << levelT_ << " dd4hep " << dd4hep_;
223 #endif
224 }
225 
227 #ifdef plotDebug
229  if (tfile.isAvailable()) {
230  tree_ = tfile->make<TTree>("TreeHGCSD", "TreeHGCSD");
231  tree_->Branch("EventID", &t_EventID_);
232  tree_->Branch("Layer", &t_Layer_);
233  tree_->Branch("ParticleCode", &t_Parcode_);
234  tree_->Branch("dEStepOriginal", &t_dEStep1_);
235  tree_->Branch("dEStepWeighted", &t_dEStep2_);
236  tree_->Branch("TrackEnergy", &t_TrackE_);
237  tree_->Branch("ThetaAngle", &t_Angle_);
238  }
239 #endif
240 }
241 
242 void HGCSD::initEvent(const BeginOfEvent* g4Event) {
243  const G4Event* evt = (*g4Event)();
244  t_EventID_ = evt->GetEventID();
245 #ifdef plotDebug
246  t_Layer_.clear();
247  t_Parcode_.clear();
248  t_dEStep1_.clear();
249  t_dEStep2_.clear();
250  t_TrackE_.clear();
251  t_Angle_.clear();
252 #endif
253 }
254 
256 #ifdef plotDebug
257  if (tree_)
258  tree_->Fill();
259 #endif
260 }
261 
262 bool HGCSD::filterHit(CaloG4Hit* aHit, double time) {
263  return ((time <= tmaxHit) && (aHit->getEnergyDeposit() > eminHit_));
264 }
265 
266 uint32_t HGCSD::setDetUnitId(ForwardSubdetector& subdet, int layer, int module, int cell, int iz, G4ThreeVector& pos) {
267  uint32_t id = numberingScheme_ ? numberingScheme_->getUnitID(subdet, layer, module, cell, iz, pos) : 0;
268  return id;
269 }
std::vector< double > t_TrackE_
Definition: HGCSD.h:69
bool dd4hep_
Definition: HGCSD.h:61
Log< level::Info, true > LogVerbatim
double getEnergyDeposit(const G4Step *) override
Definition: HGCSD.cc:99
std::vector< double > t_dEStep1_
Definition: HGCSD.h:69
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
std::vector< double > t_dEStep2_
Definition: HGCSD.h:69
int levelT_
Definition: HGCSD.h:58
double mouseBiteCut_
Definition: HGCSD.h:60
Definition: CaloSD.h:40
void setNumberCheckedHits(int val, int k=0)
Definition: CaloSD.h:126
std::vector< int > t_Layer_
Definition: HGCSD.h:68
int levelTop(int ind=0) const
std::string nameX_
Definition: HGCSD.h:51
HGCSD(const std::string &, const HGCalTBDDDConstants *, const SensitiveDetectorCatalog &, edm::ParameterSet const &, const SimTrackManager *)
Definition: HGCSD.cc:31
std::vector< double > angles_
Definition: HGCSD.h:62
Log< level::Error, false > LogError
bool storeAllG4Hits_
Definition: HGCSD.h:59
ForwardSubdetector
bool waferRot_
Definition: HGCSD.h:59
void setUseMap(bool val)
Definition: CaloSD.h:115
double eminHit
Definition: CaloSD.h:148
T getUntrackedParameter(std::string const &, T const &) const
HGCalGeometryMode::GeometryMode geom_mode_
Definition: HGCSD.h:52
double getResponseWt(const G4Track *, int k=0)
Definition: CaloSD.cc:928
double slopeMin_
Definition: HGCSD.h:57
std::unique_ptr< HGCMouseBite > mouseBite_
Definition: HGCSD.h:54
Definition: tfile.py:1
void initRun() override
Definition: HGCSD.cc:226
Tan< T >::type tan(const T &t)
Definition: Tan.h:22
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
std::vector< int > t_Parcode_
Definition: HGCSD.h:68
std::unique_ptr< HGCNumberingScheme > numberingScheme_
Definition: HGCSD.h:53
void initEvent(const BeginOfEvent *) override
Definition: HGCSD.cc:242
double tmaxHit
Definition: CaloSD.h:148
double eminHit_
Definition: HGCSD.h:55
std::vector< double > t_Angle_
Definition: HGCSD.h:70
bool rejectMB_
Definition: HGCSD.h:59
double getEnergyDeposit() const
Definition: CaloG4Hit.h:79
HLT enums.
uint32_t setDetUnitId(const G4Step *step) override
Definition: HGCSD.cc:143
void update(const BeginOfJob *) override
This routine will be called when the appropriate signal arrives.
Definition: HGCSD.cc:206
const HGCalTBDDDConstants * hgcons_
Definition: HGCSD.h:50
HGCalGeometryMode::GeometryMode geomMode() const
bool filterHit(CaloG4Hit *, double) override
Definition: HGCSD.cc:262
ForwardSubdetector myFwdSubdet_
Definition: HGCSD.h:56
void endEvent() override
Definition: HGCSD.cc:255
static void unpackHexagonIndex(const uint32_t &idx, int &subdet, int &z, int &lay, int &wafer, int &celltyp, int &cell)
uint32_t t_EventID_
Definition: HGCSD.h:67
T angle(T x1, T y1, T z1, T x2, T y2, T z2)
Definition: angle.h:11