CMS 3D CMS Logo

HGCScintSD.cc
Go to the documentation of this file.
1 // File: HGCScintSD.cc
3 // Description: Sensitive Detector class for the Scintillator part of
4 // High Granularity Calorimeter
6 
17 #include "G4LogicalVolumeStore.hh"
18 #include "G4LogicalVolume.hh"
19 #include "G4Step.hh"
20 #include "G4Track.hh"
21 #include "G4ParticleTable.hh"
22 #include "G4VProcess.hh"
23 #include "G4Trap.hh"
24 
25 #include <fstream>
26 #include <iomanip>
27 #include <iostream>
28 #include <memory>
29 
30 //#define EDM_ML_DEBUG
31 
33  const HGCalDDDConstants* hgc,
34  const SensitiveDetectorCatalog& clg,
35  edm::ParameterSet const& p,
36  const SimTrackManager* manager)
37  : CaloSD(name,
38  clg,
39  p,
40  manager,
41  (float)(p.getParameter<edm::ParameterSet>("HGCSD").getParameter<double>("TimeSliceUnit")),
42  p.getParameter<edm::ParameterSet>("HGCSD").getParameter<bool>("IgnoreTrackID")),
43  hgcons_(hgc),
44  slopeMin_(0),
45  levelT1_(99),
46  levelT2_(99),
47  firstLayer_(0) {
48  numberingScheme_.reset(nullptr);
49 
50  edm::ParameterSet m_HGC = p.getParameter<edm::ParameterSet>("HGCScintSD");
51  eminHit_ = m_HGC.getParameter<double>("EminHit") * CLHEP::MeV;
52  fiducialCut_ = m_HGC.getParameter<bool>("FiducialCut");
53  distanceFromEdge_ = m_HGC.getParameter<double>("DistanceFromEdge");
54  useBirk_ = m_HGC.getParameter<bool>("UseBirkLaw");
55  birk1_ = m_HGC.getParameter<double>("BirkC1") * (CLHEP::g / (CLHEP::MeV * CLHEP::cm2));
56  birk2_ = m_HGC.getParameter<double>("BirkC2");
57  birk3_ = m_HGC.getParameter<double>("BirkC3");
58  storeAllG4Hits_ = m_HGC.getParameter<bool>("StoreAllG4Hits");
59  checkID_ = m_HGC.getUntrackedParameter<bool>("CheckID");
60  fileName_ = m_HGC.getUntrackedParameter<std::string>("TileFileName");
61  verbose_ = m_HGC.getUntrackedParameter<int>("Verbosity");
62 
63  if (storeAllG4Hits_) {
64  setUseMap(false);
66  }
67 
68  //this is defined in the hgcsens.xml
69  G4String myName = name;
71  nameX_ = "HGCal";
72  if (myName.find("HitsHEback") != std::string::npos) {
74  nameX_ = "HGCalHEScintillatorSensitive";
75  }
76 
77 #ifdef EDM_ML_DEBUG
78  edm::LogVerbatim("HGCSim") << "**************************************************"
79  << "\n"
80  << "* *"
81  << "\n"
82  << "* Constructing a HGCScintSD with name " << name << "\n"
83  << "* *"
84  << "\n"
85  << "**************************************************";
86 #endif
87  edm::LogVerbatim("HGCSim") << "HGCScintSD:: Threshold for storing hits: " << eminHit_ << " for " << nameX_
88  << " detector " << mydet_ << " File " << fileName_;
89  edm::LogVerbatim("HGCSim") << "Flag for storing individual Geant4 Hits " << storeAllG4Hits_;
90  edm::LogVerbatim("HGCSim") << "Fiducial volume cut with cut from eta/phi "
91  << "boundary " << fiducialCut_ << " at " << distanceFromEdge_;
92  edm::LogVerbatim("HGCSim") << "Use of Birks law is set to " << useBirk_
93  << " with three constants kB = " << birk1_ << ", C1 = " << birk2_ << ", C2 = " << birk3_;
94 
95  if (!fileName_.empty()) {
96  edm::FileInPath filetmp("SimG4CMS/Calo/data/" + fileName_);
97  std::string fileName = filetmp.fullPath();
98  std::ifstream fInput(fileName.c_str());
99  if (!fInput.good()) {
100  edm::LogVerbatim("HGCSim") << "Cannot open file " << fileName;
101  } else {
102  char buffer[80];
103  while (fInput.getline(buffer, 80)) {
104  std::vector<std::string> items = CaloSimUtils::splitString(std::string(buffer));
105  if (items.size() > 2) {
106  int layer = std::atoi(items[0].c_str());
107  int ring = std::atoi(items[1].c_str());
108  int phi = std::atoi(items[2].c_str());
109  tiles_.emplace_back(HGCalTileIndex::tileIndex(layer, ring, phi));
110  }
111  }
112  edm::LogVerbatim("HGCSim") << "Reads in " << tiles_.size() << " tile information from " << fileName_;
113  fInput.close();
114  }
115  }
116 }
117 
118 double HGCScintSD::getEnergyDeposit(const G4Step* aStep) {
119  double r = aStep->GetPreStepPoint()->GetPosition().perp();
120  double z = std::abs(aStep->GetPreStepPoint()->GetPosition().z());
121 #ifdef EDM_ML_DEBUG
122  G4int parCode = aStep->GetTrack()->GetDefinition()->GetPDGEncoding();
123  G4String parName = aStep->GetTrack()->GetDefinition()->GetParticleName();
124  G4LogicalVolume* lv = aStep->GetPreStepPoint()->GetPhysicalVolume()->GetLogicalVolume();
125  edm::LogVerbatim("HGCSim") << "HGCScintSD: Hit from standard path from " << lv->GetName() << " for Track "
126  << aStep->GetTrack()->GetTrackID() << " (" << parCode << ":" << parName << ") R = " << r
127  << " Z = " << z << " slope = " << r / z << ":" << slopeMin_;
128 #endif
129  // Apply fiducial cut
130  if (r < z * slopeMin_) {
131 #ifdef EDM_ML_DEBUG
132  edm::LogVerbatim("HGCSim") << "HGCScintSD: Fiducial Volume cut";
133 #endif
134  return 0.0;
135  }
136 
137  double wt1 = getResponseWt(aStep->GetTrack());
138  double wt2 = aStep->GetTrack()->GetWeight();
139  double wt3 = (useBirk_ ? getAttenuation(aStep, birk1_, birk2_, birk3_) : 1.0);
140  double destep = weight_ * wt1 * wt3 * (aStep->GetTotalEnergyDeposit());
141  if (wt2 > 0)
142  destep *= wt2;
143 #ifdef EDM_ML_DEBUG
144  edm::LogVerbatim("HGCalSim") << "HGCScintSD: weights= " << weight_ << ":" << wt1 << ":" << wt2 << ":" << wt3
145  << " Total weight " << weight_ * wt1 * wt2 * wt3
146  << " deStep: " << aStep->GetTotalEnergyDeposit() << ":" << destep;
147 #endif
148  return destep;
149 }
150 
151 uint32_t HGCScintSD::setDetUnitId(const G4Step* aStep) {
152  const G4StepPoint* preStepPoint = aStep->GetPreStepPoint();
153  const G4VTouchable* touch = preStepPoint->GetTouchable();
154 
155 #ifdef EDM_ML_DEBUG
156  edm::LogVerbatim("HGCSim") << "DepthsTop: " << touch->GetHistoryDepth() << ":" << levelT1_ << ":" << levelT2_;
157  printDetectorLevels(touch);
158 #endif
159  //determine the exact position in global coordinates in the mass geometry
160  G4ThreeVector hitPoint = preStepPoint->GetPosition();
161  float globalZ = touch->GetTranslation(0).z();
162  int iz(globalZ > 0 ? 1 : -1);
163 
164  int layer(0), module(-1), cell(-1);
166  layer = touch->GetReplicaNumber(1);
167  } else if ((touch->GetHistoryDepth() == levelT1_) || (touch->GetHistoryDepth() == levelT2_)) {
168  layer = touch->GetReplicaNumber(0);
169 #ifdef EDM_ML_DEBUG
170  edm::LogVerbatim("HGCSim") << "DepthsTop: " << touch->GetHistoryDepth() << ":" << levelT1_ << ":" << levelT2_
171  << " name " << touch->GetVolume(0)->GetName() << " layer:module:cell " << layer << ":"
172  << module << ":" << cell;
173 #endif
174  } else {
175  layer = touch->GetReplicaNumber(3);
176  module = touch->GetReplicaNumber(2);
177  cell = touch->GetReplicaNumber(1);
178 #ifdef EDM_ML_DEBUG
179  edm::LogVerbatim("HGCSim") << "DepthsInside: " << touch->GetHistoryDepth() << " name "
180  << touch->GetVolume(0)->GetName() << " layer:module:cell " << layer << ":" << module
181  << ":" << cell;
182 #endif
183  }
184 #ifdef EDM_ML_DEBUG
185  G4Material* mat = aStep->GetPreStepPoint()->GetMaterial();
186  edm::LogVerbatim("HGCSim") << "Depths: " << touch->GetHistoryDepth() << " name " << touch->GetVolume(0)->GetName()
187  << ":" << touch->GetReplicaNumber(0) << " " << touch->GetVolume(1)->GetName() << ":"
188  << touch->GetReplicaNumber(1) << " " << touch->GetVolume(2)->GetName() << ":"
189  << touch->GetReplicaNumber(2) << " " << touch->GetVolume(3)->GetName() << ":"
190  << touch->GetReplicaNumber(3) << " " << touch->GetVolume(4)->GetName() << ":"
191  << touch->GetReplicaNumber(4) << " "
192  << " layer:module:cell " << layer << ":" << module << ":" << cell << " Material "
193  << mat->GetName() << ":" << mat->GetRadlen();
194 #endif
195  // The following statement should be examined later before elimination
196  if (aStep->GetPreStepPoint()->GetMaterial()->GetRadlen() > 100000.)
197  return 0;
198 
199  uint32_t id = setDetUnitId(layer, module, cell, iz, hitPoint);
200  bool debug(false);
201  if (!tiles_.empty()) {
202  HGCScintillatorDetId hid(id);
203  int indx = HGCalTileIndex::tileIndex(firstLayer_ + hid.layer(), hid.ring(), hid.iphi());
204  if (std::find(tiles_.begin(), tiles_.end(), indx) != tiles_.end())
205  debug = true;
206  }
207  if (debug)
208  edm::LogVerbatim("HGCSim") << "Layer:module:cell:iz " << layer << ":" << module << ":" << cell << ":" << iz
209  << " Point (" << hitPoint.x() << ", " << hitPoint.y() << ", " << hitPoint.z() << ") "
210  << HGCScintillatorDetId(id);
211 
212  if (!isItinFidVolume(hitPoint)) {
213 #ifdef EDM_ML_DEBUG
214  edm::LogVerbatim("HGCSim") << "ID " << std::hex << id << std::dec << " " << HGCScintillatorDetId(id)
215  << " is rejected by fiducilal volume cut";
216 #endif
217  id = 0;
218  }
219  if ((id != 0) && checkID_) {
220  HGCScintillatorDetId hid1(id);
221  std::string_view pid =
222  ((hgcons_->cassetteShiftScintillator(hid1.zside(), hid1.layer(), hid1.iphi())) ? "HGCSim" : "HGCalSim");
223  bool debug = (verbose_ > 0) ? true : false;
225  double dx = xy.first - (hitPoint.x() / CLHEP::cm);
226  double dy = xy.second - (hitPoint.y() / CLHEP::cm);
227  double diff = std::sqrt(dx * dx + dy * dy);
228  constexpr double tol = 10.0;
229  bool valid = hgcons_->isValidTrap(hid1.zside(), hid1.layer(), hid1.ring(), hid1.iphi());
230  if ((diff > tol) || (!valid))
231  pid = "HGCalError";
232  edm::LogVerbatim(pid) << "CheckID " << HGCScintillatorDetId(id) << " input position: (" << hitPoint.x() / CLHEP::cm
233  << ", " << hitPoint.y() / CLHEP::cm << "); position from ID (" << xy.first << ", "
234  << xy.second << ") distance " << diff << " Valid " << valid
235  << " Rho = " << hitPoint.perp() / CLHEP::cm;
236  }
237  return id;
238 }
239 
240 void HGCScintSD::update(const BeginOfJob* job) {
241  if (hgcons_ != nullptr) {
244  levelT1_ = hgcons_->levelTop(0);
245  levelT2_ = hgcons_->levelTop(1);
246  firstLayer_ = hgcons_->firstLayer() - 1;
247 #ifdef EDM_ML_DEBUG
248  edm::LogVerbatim("HGCSim") << "HGCScintSD::Initialized with mode " << geom_mode_ << " Slope cut " << slopeMin_
249  << " top Level " << levelT1_ << ":" << levelT2_ << " FirstLayer " << firstLayer_;
250 #endif
251 
252  numberingScheme_ = std::make_unique<HGCalNumberingScheme>(*hgcons_, mydet_, nameX_, fileName_);
253  } else {
254  throw cms::Exception("Unknown", "HGCScintSD") << "Cannot find HGCalDDDConstants for " << nameX_ << "\n";
255  }
256 }
257 
259 
260 bool HGCScintSD::filterHit(CaloG4Hit* aHit, double time) {
261  return ((time <= tmaxHit) && (aHit->getEnergyDeposit() > eminHit_));
262 }
263 
264 uint32_t HGCScintSD::setDetUnitId(int layer, int module, int cell, int iz, G4ThreeVector& pos) {
265  uint32_t id = numberingScheme_ ? numberingScheme_->getUnitID(layer, module, cell, iz, pos, weight_) : 0;
266  return id;
267 }
268 
269 bool HGCScintSD::isItinFidVolume(const G4ThreeVector& pos) {
270  if (fiducialCut_) {
271  return (hgcons_->distFromEdgeTrap(pos.x(), pos.y(), pos.z()) > distanceFromEdge_);
272  } else {
273  return true;
274  }
275 }
double birk2_
Definition: HGCScintSD.h:50
Log< level::Info, true > LogVerbatim
HGCalGeometryMode::GeometryMode geom_mode_
Definition: HGCScintSD.h:45
int levelT2_
Definition: HGCScintSD.h:47
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
constexpr int iphi() const
get the phi index
bool cassetteShiftScintillator(int zside, int layer, int iphi) const
double birk1_
Definition: HGCScintSD.h:50
HGCScintSD(const std::string &, const HGCalDDDConstants *, const SensitiveDetectorCatalog &, edm::ParameterSet const &, const SimTrackManager *)
Definition: HGCScintSD.cc:32
Definition: CaloSD.h:40
void setNumberCheckedHits(int val, int k=0)
Definition: CaloSD.h:126
std::string fullPath() const
Definition: FileInPath.cc:161
double distFromEdgeTrap(double x, double y, double z) const
double distanceFromEdge_
Definition: HGCScintSD.h:46
bool checkID_
Definition: HGCScintSD.h:51
std::vector< int > tiles_
Definition: HGCScintSD.h:53
constexpr int zside() const
get the z-side of the cell (1/-1)
int firstLayer() const
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
HGCalGeometryMode::GeometryMode geomMode() const
uint32_t setDetUnitId(const G4Step *step) override
Definition: HGCScintSD.cc:151
int levelT1_
Definition: HGCScintSD.h:47
void setUseMap(bool val)
Definition: CaloSD.h:115
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
Definition: Activities.doc:4
bool fiducialCut_
Definition: HGCScintSD.h:48
bool useBirk_
Definition: HGCScintSD.h:49
const HGCalDDDConstants * hgcons_
Definition: HGCScintSD.h:41
T getUntrackedParameter(std::string const &, T const &) const
int32_t tileIndex(int32_t layer, int32_t ring, int32_t phi)
double getResponseWt(const G4Track *, int k=0)
Definition: CaloSD.cc:929
std::vector< std::string > splitString(const std::string &)
Definition: CaloSimUtils.cc:3
T sqrt(T t)
Definition: SSEVec.h:23
double weight_
Definition: HGCScintSD.h:50
bool isItinFidVolume(const G4ThreeVector &)
Definition: HGCScintSD.cc:269
int verbose_
Definition: HGCScintSD.h:47
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
bool isValidTrap(int zside, int lay, int ieta, int iphi) const
void initRun() override
Definition: HGCScintSD.cc:258
double tmaxHit
Definition: CaloSD.h:148
double getEnergyDeposit(const G4Step *) override
Definition: HGCScintSD.cc:118
#define debug
Definition: HDRShower.cc:19
double eminHit_
Definition: HGCScintSD.h:46
double minSlope() const
std::string fileName_
Definition: HGCScintSD.h:52
double slopeMin_
Definition: HGCScintSD.h:46
double getAttenuation(const G4Step *aStep, double birk1, double birk2, double birk3) const
Definition: CaloSD.cc:728
double getEnergyDeposit() const
Definition: CaloG4Hit.h:79
std::unique_ptr< HGCalNumberingScheme > numberingScheme_
Definition: HGCScintSD.h:42
std::pair< float, float > locateCell(int cell, int lay, int type, bool reco) const
int firstLayer_
Definition: HGCScintSD.h:47
void printDetectorLevels(const G4VTouchable *) const
Definition: CaloSD.cc:1159
std::string nameX_
Definition: HGCScintSD.h:44
HLT enums.
constexpr int layer() const
get the layer #
constexpr int ring() const
get the eta index
DetId::Detector mydet_
Definition: HGCScintSD.h:43
int levelTop(int ind=0) const
void update(const BeginOfJob *) override
This routine will be called when the appropriate signal arrives.
Definition: HGCScintSD.cc:240
double birk3_
Definition: HGCScintSD.h:50
bool storeAllG4Hits_
Definition: HGCScintSD.h:48
bool filterHit(CaloG4Hit *, double) override
Definition: HGCScintSD.cc:260