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