test
CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
HCalSD.cc
Go to the documentation of this file.
1 // File: HCalSD.cc
3 // Description: Sensitive Detector class for calorimeters
5 
16 
24 
25 #include "G4LogicalVolumeStore.hh"
26 #include "G4LogicalVolume.hh"
27 #include "G4Step.hh"
28 #include "G4Track.hh"
29 #include "G4ParticleTable.hh"
30 #include "G4VProcess.hh"
31 
32 #include "G4SystemOfUnits.hh"
33 #include "G4PhysicalConstants.hh"
34 
35 #include <iostream>
36 #include <fstream>
37 #include <iomanip>
38 
39 //#define DebugLog
40 //#define plotDebug
41 
42 HCalSD::HCalSD(G4String name, const DDCompactView & cpv,
43  const SensitiveDetectorCatalog & clg,
44  edm::ParameterSet const & p, const SimTrackManager* manager) :
45  CaloSD(name, cpv, clg, p, manager,
46  (float)(p.getParameter<edm::ParameterSet>("HCalSD").getParameter<double>("TimeSliceUnit")),
47  p.getParameter<edm::ParameterSet>("HCalSD").getParameter<bool>("IgnoreTrackID")),
48  hcalConstants(0), numberingFromDDD(0), numberingScheme(0), showerLibrary(0),
49  hfshower(0), showerParam(0), showerPMT(0), showerBundle(0), m_HEDarkening(0),
50  m_HFDarkening(0) {
51 
52  //static SimpleConfigurable<double> bk1(0.013, "HCalSD:BirkC1");
53  //static SimpleConfigurable<double> bk2(0.0568,"HCalSD:BirkC2");
54  //static SimpleConfigurable<double> bk3(1.75, "HCalSD:BirkC3");
55  // Values from NIM 80 (1970) 239-244: as implemented in Geant3
56 
58  useBirk = m_HC.getParameter<bool>("UseBirkLaw");
59  birk1 = m_HC.getParameter<double>("BirkC1")*(g/(MeV*cm2));
60  birk2 = m_HC.getParameter<double>("BirkC2");
61  birk3 = m_HC.getParameter<double>("BirkC3");
62  useShowerLibrary = m_HC.getParameter<bool>("UseShowerLibrary");
63  useParam = m_HC.getParameter<bool>("UseParametrize");
64  testNumber = m_HC.getParameter<bool>("TestNumberingScheme");
65  usePMTHit = m_HC.getParameter<bool>("UsePMTHits");
66  betaThr = m_HC.getParameter<double>("BetaThreshold");
67  eminHitHB = m_HC.getParameter<double>("EminHitHB")*MeV;
68  eminHitHE = m_HC.getParameter<double>("EminHitHE")*MeV;
69  eminHitHO = m_HC.getParameter<double>("EminHitHO")*MeV;
70  eminHitHF = m_HC.getParameter<double>("EminHitHF")*MeV;
71  useFibreBundle = m_HC.getParameter<bool>("UseFibreBundleHits");
72  deliveredLumi = m_HC.getParameter<double>("DelivLuminosity");
73  bool ageingFlagHE= m_HC.getParameter<bool>("HEDarkening");
74  bool ageingFlagHF= m_HC.getParameter<bool>("HFDarkening");
75  useHF = m_HC.getUntrackedParameter<bool>("UseHF",true);
76  bool forTBH2 = m_HC.getUntrackedParameter<bool>("ForTBH2",false);
77  useLayerWt = m_HC.getUntrackedParameter<bool>("UseLayerWt",false);
78  std::string file = m_HC.getUntrackedParameter<std::string>("WtFile","None");
79  edm::ParameterSet m_HF = p.getParameter<edm::ParameterSet>("HFShower");
80  applyFidCut = m_HF.getParameter<bool>("ApplyFiducialCut");
81 
82 #ifdef DebugLog
83  LogDebug("HcalSim") << "***************************************************"
84  << "\n"
85  << "* *"
86  << "\n"
87  << "* Constructing a HCalSD with name " << name << "\n"
88  << "* *"
89  << "\n"
90  << "***************************************************";
91 #endif
92  edm::LogInfo("HcalSim") << "HCalSD:: Use of HF code is set to " << useHF
93  << "\nUse of shower parametrization set to "
94  << useParam << "\nUse of shower library is set to "
95  << useShowerLibrary << "\nUse PMT Hit is set to "
96  << usePMTHit << " with beta Threshold "<< betaThr
97  << "\nUSe of FibreBundle Hit set to "<<useFibreBundle
98  << "\n Use of Birks law is set to "
99  << useBirk << " with three constants kB = "
100  << birk1 << ", C1 = " << birk2 << ", C2 = " << birk3;
101  edm::LogInfo("HcalSim") << "HCalSD:: Suppression Flag " << suppressHeavy
102  << " protons below " << kmaxProton << " MeV,"
103  << " neutrons below " << kmaxNeutron << " MeV and"
104  << " ions below " << kmaxIon << " MeV\n"
105  << " Threshold for storing hits in HB: "
106  << eminHitHB << " HE: " << eminHitHE << " HO: "
107  << eminHitHO << " HF: " << eminHitHF << "\n"
108  << "Delivered luminosity for Darkening "
109  << deliveredLumi << " Flag (HE) " << ageingFlagHE
110  << " Flag (HF) " << ageingFlagHF << "\n"
111  << "Application of Fiducial Cut " << applyFidCut;
112 
113  HcalNumberingScheme* scheme;
114  if (testNumber || forTBH2)
115  scheme = dynamic_cast<HcalNumberingScheme*>(new HcalTestNumberingScheme(forTBH2));
116  else
117  scheme = new HcalNumberingScheme();
118  setNumberingScheme(scheme);
119 
120  const G4LogicalVolumeStore * lvs = G4LogicalVolumeStore::GetInstance();
121  std::vector<G4LogicalVolume *>::const_iterator lvcite;
122  G4LogicalVolume* lv;
123  std::string attribute, value;
124  if (useHF) {
125  if (useParam) {
126  showerParam = new HFShowerParam(name, cpv, p);
127  } else {
128  if (useShowerLibrary) showerLibrary = new HFShowerLibrary(name, cpv, p);
129  hfshower = new HFShower(name, cpv, p, 0);
130  }
131 
132  // HF volume names
133  attribute = "Volume";
134  value = "HF";
135  DDSpecificsFilter filter0;
136  DDValue ddv0(attribute, value, 0);
137  filter0.setCriteria(ddv0, DDCompOp::equals);
138  DDFilteredView fv0(cpv);
139  fv0.addFilter(filter0);
140  hfNames = getNames(fv0);
141  fv0.firstChild();
142  DDsvalues_type sv0(fv0.mergedSpecifics());
143  std::vector<double> temp = getDDDArray("Levels",sv0);
144  edm::LogInfo("HcalSim") << "HCalSD: Names to be tested for " << attribute
145  << " = " << value << " has " << hfNames.size()
146  << " elements";
147  for (unsigned int i=0; i < hfNames.size(); ++i) {
148  G4String namv = hfNames[i];
149  lv = 0;
150  for(lvcite=lvs->begin(); lvcite!=lvs->end(); lvcite++)
151  if((*lvcite)->GetName()==namv) {
152  lv = (*lvcite);
153  break;
154  }
155  hfLV.push_back(lv);
156  int level = static_cast<int>(temp[i]);
157  hfLevels.push_back(level);
158  edm::LogInfo("HcalSim") << "HCalSD: HF[" << i << "] = " << hfNames[i]
159  << " LV " << hfLV[i] << " at level "
160  << hfLevels[i];
161  }
162 
163  // HF Fibre volume names
164  value = "HFFibre";
165  DDSpecificsFilter filter1;
166  DDValue ddv1(attribute,value,0);
167  filter1.setCriteria(ddv1, DDCompOp::equals);
168  DDFilteredView fv1(cpv);
169  fv1.addFilter(filter1);
170  fibreNames = getNames(fv1);
171  edm::LogInfo("HcalSim") << "HCalSD: Names to be tested for " << attribute
172  << " = " << value << ":";
173  for (unsigned int i=0; i<fibreNames.size(); ++i) {
174  G4String namv = fibreNames[i];
175  lv = 0;
176  for (lvcite = lvs->begin(); lvcite != lvs->end(); ++lvcite) {
177  if ((*lvcite)->GetName() == namv) {
178  lv = (*lvcite);
179  break;
180  }
181  }
182  fibreLV.push_back(lv);
183  edm::LogInfo("HcalSim") << "HCalSD: (" << i << ") " << fibreNames[i]
184  << " LV " << fibreLV[i];
185  }
186 
187  // HF PMT volume names
188  value = "HFPMT";
189  DDSpecificsFilter filter3;
190  DDValue ddv3(attribute,value,0);
191  filter3.setCriteria(ddv3,DDCompOp::equals);
192  DDFilteredView fv3(cpv);
193  fv3.addFilter(filter3);
194  std::vector<G4String> pmtNames = getNames(fv3);
195  edm::LogInfo("HcalSim") << "HCalSD: Names to be tested for " << attribute
196  << " = " << value << " have " << pmtNames.size()
197  << " entries";
198  for (unsigned int i=0; i<pmtNames.size(); ++i) {
199  G4String namv = pmtNames[i];
200  lv = 0;
201  for (lvcite = lvs->begin(); lvcite != lvs->end(); ++lvcite)
202  if ((*lvcite)->GetName() == namv) {
203  lv = (*lvcite);
204  break;
205  }
206  pmtLV.push_back(lv);
207  edm::LogInfo("HcalSim") << "HCalSD: (" << i << ") " << pmtNames[i]
208  << " LV " << pmtLV[i];
209  }
210  if (pmtNames.size() > 0) showerPMT = new HFShowerPMT (name, cpv, p);
211 
212  // HF Fibre bundles
213  value = "HFFibreBundleStraight";
214  DDSpecificsFilter filter4;
215  DDValue ddv4(attribute,value,0);
216  filter4.setCriteria(ddv4,DDCompOp::equals);
217  DDFilteredView fv4(cpv);
218  fv4.addFilter(filter4);
219  std::vector<G4String> fibreNames = getNames(fv4);
220  edm::LogInfo("HcalSim") << "HCalSD: Names to be tested for " << attribute
221  << " = " << value << " have " << fibreNames.size()
222  << " entries";
223  for (unsigned int i=0; i<fibreNames.size(); ++i) {
224  G4String namv = fibreNames[i];
225  lv = 0;
226  for (lvcite = lvs->begin(); lvcite != lvs->end(); lvcite++)
227  if ((*lvcite)->GetName() == namv) {
228  lv = (*lvcite);
229  break;
230  }
231  fibre1LV.push_back(lv);
232  edm::LogInfo("HcalSim") << "HCalSD: (" << i << ") " << fibreNames[i]
233  << " LV " << fibre1LV[i];
234  }
235 
236  // Geometry parameters for HF
237  value = "HFFibreBundleConical";
238  DDSpecificsFilter filter5;
239  DDValue ddv5(attribute,value,0);
240  filter5.setCriteria(ddv5,DDCompOp::equals);
241  DDFilteredView fv5(cpv);
242  fv5.addFilter(filter5);
243  fibreNames = getNames(fv5);
244  edm::LogInfo("HcalSim") << "HCalSD: Names to be tested for " << attribute
245  << " = " << value << " have " << fibreNames.size()
246  << " entries";
247  for (unsigned int i=0; i<fibreNames.size(); ++i) {
248  G4String namv = fibreNames[i];
249  lv = 0;
250  for (lvcite = lvs->begin(); lvcite != lvs->end(); ++lvcite)
251  if ((*lvcite)->GetName() == namv) {
252  lv = (*lvcite);
253  break;
254  }
255  fibre2LV.push_back(lv);
256  edm::LogInfo("HcalSim") << "HCalSD: (" << i << ") " << fibreNames[i]
257  << " LV " << fibre2LV[i];
258  }
259  if (fibre1LV.size() > 0 || fibre2LV.size() > 0)
260  showerBundle = new HFShowerFibreBundle (name, cpv, p);
261  }
262 
263  //Material list for HB/HE/HO sensitive detectors
264  const G4MaterialTable * matTab = G4Material::GetMaterialTable();
265  std::vector<G4Material*>::const_iterator matite;
266  attribute = "OnlyForHcalSimNumbering";
267  value = "any";
268  DDSpecificsFilter filter2;
269  DDValue ddv2(attribute,value,0);
270  filter2.setCriteria(ddv2, DDCompOp::not_equals,
271  DDLogOp::AND, true, true);
272  DDFilteredView fv2(cpv);
273  fv2.addFilter(filter2);
274  bool dodet = fv2.firstChild();
276 
277  while (dodet) {
278  const DDLogicalPart & log = fv2.logicalPart();
279  G4String namx = log.name().name();
280  if (!isItHF(namx) && !isItFibre(namx)) {
281  bool notIn = true;
282  for (unsigned int i=0; i<matNames.size(); ++i) {
283  if (!strcmp(matNames[i].c_str(),log.material().name().name().c_str())){
284  notIn = false;
285  break;
286  }
287  }
288  if (notIn) {
289  namx = log.material().name().name();
290  matNames.push_back(namx);
291  G4Material* mat = nullptr;
292  for (matite = matTab->begin(); matite != matTab->end(); ++matite) {
293  if ((*matite)->GetName() == namx) {
294  mat = (*matite);
295  break;
296  }
297  }
298  materials.push_back(mat);
299  }
300  }
301  dodet = fv2.next();
302  }
303 
304  edm::LogInfo("HcalSim") << "HCalSD: Material names for " << attribute
305  << " = " << name << ":";
306  for (unsigned int i=0; i<matNames.size(); ++i)
307  edm::LogInfo("HcalSim") << "HCalSD: (" << i << ") " << matNames[i]
308  << " pointer " << materials[i];
309 
310  mumPDG = mupPDG = 0;
311 
312  if (useLayerWt) readWeightFromFile(file);
313 
314  for (int i=0; i<9; ++i) hit_[i] = time_[i]= dist_[i] = 0;
315  hzvem = hzvhad = 0;
316 
317  if (ageingFlagHE) m_HEDarkening = new HEDarkening();
318  if (ageingFlagHF) m_HFDarkening = new HFDarkening(m_HC.getParameter<edm::ParameterSet>("HFDarkeningParameterBlock"));
319 #ifdef plotDebug
321 
322  if ( tfile.isAvailable() ) {
323  static const char * const labels[] = {"HB", "HE", "HO", "HF Absorber", "HF PMT",
324  "HF Absorber Long", "HF Absorber Short",
325  "HF PMT Long", "HF PMT Short"};
326  TFileDirectory hcDir = tfile->mkdir("ProfileFromHCalSD");
327  char name[20], title[60];
328  for (int i=0; i<9; ++i) {
329  sprintf (title, "Hit energy in %s", labels[i]);
330  sprintf (name, "HCalSDHit%d", i);
331  hit_[i] = hcDir.make<TH1F>(name, title, 2000, 0., 2000.);
332  sprintf (title, "Energy (MeV)");
333  hit_[i]->GetXaxis()->SetTitle(title);
334  hit_[i]->GetYaxis()->SetTitle("Hits");
335  sprintf (title, "Time of the hit in %s", labels[i]);
336  sprintf (name, "HCalSDTime%d", i);
337  time_[i] = hcDir.make<TH1F>(name, title, 2000, 0., 2000.);
338  sprintf (title, "Time (ns)");
339  time_[i]->GetXaxis()->SetTitle(title);
340  time_[i]->GetYaxis()->SetTitle("Hits");
341  sprintf (title, "Longitudinal profile in %s", labels[i]);
342  sprintf (name, "HCalSDDist%d", i);
343  dist_[i] = hcDir.make<TH1F>(name, title, 2000, 0., 2000.);
344  sprintf (title, "Distance (mm)");
345  dist_[i]->GetXaxis()->SetTitle(title);
346  dist_[i]->GetYaxis()->SetTitle("Hits");
347  }
348  if (useHF && (!useParam)) {
349  hzvem = hcDir.make<TH1F>("hzvem", "Longitudinal Profile (EM Part)",330,0.0,1650.0);
350  hzvem->GetXaxis()->SetTitle("Longitudinal Profile (EM Part)");
351  hzvhad = hcDir.make<TH1F>("hzvhad","Longitudinal Profile (Had Part)",330,0.0,1650.0);
352  hzvhad->GetXaxis()->SetTitle("Longitudinal Profile (Hadronic Part)");
353  }
354  }
355 #endif
356 }
357 
359 
361  if (numberingScheme) delete numberingScheme;
362  if (showerLibrary) delete showerLibrary;
363  if (hfshower) delete hfshower;
364  if (showerParam) delete showerParam;
365  if (showerPMT) delete showerPMT;
366  if (showerBundle) delete showerBundle;
367  if (m_HEDarkening) delete m_HEDarkening;
368  if (m_HFDarkening) delete m_HFDarkening;
369 }
370 
371 bool HCalSD::ProcessHits(G4Step * aStep, G4TouchableHistory * ) {
372 
373  NaNTrap( aStep ) ;
374 
375  if (aStep == NULL) {
376  return true;
377  } else {
378  G4LogicalVolume* lv =
379  aStep->GetPreStepPoint()->GetPhysicalVolume()->GetLogicalVolume();
380  G4String nameVolume = lv->GetName();
381  if (isItHF(aStep)) {
382  G4int parCode = aStep->GetTrack()->GetDefinition()->GetPDGEncoding();
383  double weight(1.0);
384  if (m_HFDarkening != 0) {
385  G4ThreeVector hitPoint = aStep->GetPreStepPoint()->GetPosition();
386  double r = hitPoint.perp()/CLHEP::cm;
387  double z = std::abs(hitPoint.z())/CLHEP::cm;
388  double dose_acquired = 0.;
390  unsigned int hfZLayer = (int)((z - HFDarkening::lowZLimit)/5);
391  if (hfZLayer >= HFDarkening::upperZLimit) hfZLayer = (HFDarkening::upperZLimit-1);
392  float normalized_lumi = m_HFDarkening->int_lumi(deliveredLumi);
393  for (int i = hfZLayer; i != HFDarkening::numberOfZLayers; ++i) {
394  dose_acquired = m_HFDarkening->dose(i,r);
395  weight *= m_HFDarkening->degradation(normalized_lumi*dose_acquired);
396  }
397  }
398 #ifdef DebugLog
399  LogDebug("HcalSim") << "HCalSD: HFLumiDarkening at r = " << r
400  << ", z = " << z << " Dose " << dose_acquired
401  << " weight " << weight;
402 #endif
403  }
404  if (useParam) {
405 #ifdef DebugLog
406  LogDebug("HcalSim") << "HCalSD: " << getNumberOfHits()
407  << " hits from parametrization in " << nameVolume
408  << " for Track " << aStep->GetTrack()->GetTrackID()
409  <<" (" << aStep->GetTrack()->GetDefinition()->GetParticleName()
410  <<")";
411 #endif
412  getFromParam(aStep, weight);
413 #ifdef DebugLog
414  LogDebug("HcalSim") << "HCalSD: " << getNumberOfHits()
415  << " hits afterParamS*";
416 #endif
417  } else {
418  bool notaMuon = true;
419  if (parCode == mupPDG || parCode == mumPDG ) notaMuon = false;
420  if (useShowerLibrary && notaMuon) {
421 #ifdef DebugLog
422  LogDebug("HcalSim") << "HCalSD: Starts shower library from "
423  << nameVolume << " for Track "
424  << aStep->GetTrack()->GetTrackID() << " ("
425  << aStep->GetTrack()->GetDefinition()->GetParticleName() << ")";
426 #endif
427  getFromLibrary(aStep, weight);
428  } else if (isItFibre(lv)) {
429 #ifdef DebugLog
430  LogDebug("HcalSim") << "HCalSD: Hit at Fibre in " << nameVolume
431  << " for Track "
432  << aStep->GetTrack()->GetTrackID() <<" ("
433  << aStep->GetTrack()->GetDefinition()->GetParticleName() << ")";
434 #endif
435  hitForFibre(aStep, weight);
436  }
437  }
438  } else if (isItPMT(lv)) {
439 #ifdef DebugLog
440  LogDebug("HcalSim") << "HCalSD: Hit from PMT parametrization from "
441  << nameVolume << " for Track "
442  << aStep->GetTrack()->GetTrackID() << " ("
443  << aStep->GetTrack()->GetDefinition()->GetParticleName() << ")";
444 #endif
445  if (usePMTHit && showerPMT) getHitPMT(aStep);
446  } else if (isItStraightBundle(lv) || isItConicalBundle(lv)) {
447 #ifdef DebugLog
448  LogDebug("HcalSim") << "HCalSD: Hit from FibreBundle from "
449  << nameVolume << " for Track "
450  << aStep->GetTrack()->GetTrackID() << " ("
451  << aStep->GetTrack()->GetDefinition()->GetParticleName() << ")";
452 #endif
455  } else {
456 #ifdef DebugLog
457  LogDebug("HcalSim") << "HCalSD: Hit from standard path from "
458  << nameVolume << " for Track "
459  << aStep->GetTrack()->GetTrackID() << " ("
460  << aStep->GetTrack()->GetDefinition()->GetParticleName() << ")";
461 #endif
462  if (getStepInfo(aStep)) {
463 #ifdef plotDebug
464  if (edepositEM+edepositHAD > 0)
465  plotProfile(aStep, aStep->GetPreStepPoint()->GetPosition(),
466  edepositEM+edepositHAD,aStep->GetPostStepPoint()->GetGlobalTime(),0);
467 #endif
468  if (hitExists() == false && edepositEM+edepositHAD>0.) currentHit = createNewHit();
469  }
470  }
471  return true;
472  }
473 }
474 
475 double HCalSD::getEnergyDeposit(G4Step* aStep) {
476  double destep = aStep->GetTotalEnergyDeposit();
477  double weight = 1;
478  G4Track* theTrack = aStep->GetTrack();
479 
480  const G4VTouchable* touch = aStep->GetPreStepPoint()->GetTouchable();
481  int depth = (touch->GetReplicaNumber(0))%10;
482  int det = ((touch->GetReplicaNumber(1))/1000)-3;
483  if (depth==0 && (det==0 || det==1)) weight = layer0wt[det];
484  if (useLayerWt) {
485  int lay = (touch->GetReplicaNumber(0)/10)%100 + 1;
486  G4ThreeVector hitPoint = aStep->GetPreStepPoint()->GetPosition();
487  weight = layerWeight(det+3, hitPoint, depth, lay);
488  }
489 
490  if (m_HEDarkening !=0 && det == 1) {
491  int lay = (touch->GetReplicaNumber(0)/10)%100 + 1;
492  int ieta;
493  uint32_t detid = setDetUnitId(aStep);
494  if(testNumber) {
495  int det, z, depth, eta, phi, lay;
496  HcalTestNumbering::unpackHcalIndex(detid,det,z,depth,eta,phi,lay);
497  ieta = eta;
498  }
499  else ieta = HcalDetId(detid).ietaAbs();
500 #ifdef DebugLog
501  edm::LogInfo("HcalSim") << "HCalSD:HE_Darkening >>> ieta: "<< ieta //<< " vs. ietaAbs(): " << HcalDetId(detid).ietaAbs()
502  << " lay: " << lay-2;
503 #endif
504  float dweight = m_HEDarkening->degradation(deliveredLumi,ieta,lay-2);//NB:diff. layer count
505  weight *= dweight;
506 #ifdef DebugLog
507  edm::LogInfo("HcalSim") << "HCalSD: >>> Lumi: " << deliveredLumi
508  << " coefficient = " << dweight;
509 #endif
510  }
511 
512  if (suppressHeavy) {
513  TrackInformation * trkInfo = (TrackInformation *)(theTrack->GetUserInformation());
514  if (trkInfo) {
515  int pdg = theTrack->GetDefinition()->GetPDGEncoding();
516  if (!(trkInfo->isPrimary())) { // Only secondary particles
517  double ke = theTrack->GetKineticEnergy()/MeV;
518  if ( pdg/1000000000 == 1 && (pdg/10000)%100 > 0 &&
519  (pdg/10)%100 > 0 && ke <kmaxIon ) weight = 0;
520  if ((pdg == 2212) && (ke < kmaxProton)) weight = 0;
521  if ((pdg == 2112) && (ke < kmaxNeutron)) weight = 0;
522 #ifdef DebugLog
523  if (weight == 0)
524  edm::LogInfo("HcalSim") << "HCalSD:Ignore Track "
525  << theTrack->GetTrackID() << " Type "
526  << theTrack->GetDefinition()->GetParticleName()
527  << " Kinetic Energy " << ke << " MeV";
528 #endif
529  }
530  }
531  }
532 #ifdef DebugLog
533  double weight0 = weight;
534 #endif
535  if (useBirk) {
536  G4Material* mat = aStep->GetPreStepPoint()->GetMaterial();
537  if (isItScintillator(mat)) weight *= getAttenuation(aStep, birk1, birk2, birk3);
538  }
539  double wt1 = getResponseWt(theTrack);
540  double wt2 = theTrack->GetWeight();
541 #ifdef DebugLog
542  edm::LogInfo("HcalSim") << "HCalSD: Detector " << det+3 << " Depth " << depth
543  << " weight " << weight0 << " " << weight << " " << wt1
544  << " " << wt2;
545 #endif
546  double edep = weight*wt1*destep;
547  if(wt2 > 0.0) { edep *= wt2; }
548  return edep;
549 }
550 
551 uint32_t HCalSD::setDetUnitId(G4Step * aStep) {
552 
553  G4StepPoint* preStepPoint = aStep->GetPreStepPoint();
554  const G4VTouchable* touch = preStepPoint->GetTouchable();
555  G4ThreeVector hitPoint = preStepPoint->GetPosition();
556 
557  int depth = (touch->GetReplicaNumber(0))%10 + 1;
558  int lay = (touch->GetReplicaNumber(0)/10)%100 + 1;
559  int det = (touch->GetReplicaNumber(1))/1000;
560 
561  return setDetUnitId (det, hitPoint, depth, lay);
562 }
563 
565  if (scheme != 0) {
566  edm::LogInfo("HcalSim") << "HCalSD: updates numbering scheme for " << GetName();
567  if (numberingScheme) delete numberingScheme;
568  numberingScheme = scheme;
569  }
570 }
571 
572 void HCalSD::update(const BeginOfJob * job) {
573 
574  const edm::EventSetup* es = (*job)();
576  es->get<HcalSimNumberingRecord>().get(hdc);
577  if (hdc.isValid()) {
578  hcalConstants = (HcalDDDSimConstants*)(&(*hdc));
579  } else {
580  edm::LogError("HcalSim") << "HCalSD : Cannot find HcalDDDSimConstant";
581  throw cms::Exception("Unknown", "HCalSD") << "Cannot find HcalDDDSimConstant" << "\n";
582  }
583 
585 
586  edm::LogInfo("HcalSim") << "Maximum depth for HF " << hcalConstants->getMaxDepth(2);
587 
588  //Special Geometry parameters
590  edm::LogInfo("HcalSim") << "HCalSD: " << gpar.size()<< " gpar (cm)";
591  for (unsigned int ig=0; ig<gpar.size(); ig++)
592  edm::LogInfo("HcalSim") << "HCalSD: gpar[" << ig << "] = "
593  << gpar[ig]/cm << " cm";
594 
595  //Layer0 Weight
597  edm::LogInfo("HcalSim") << "HCalSD: " << layer0wt.size() << " Layer0Wt";
598  for (unsigned int it=0; it<layer0wt.size(); ++it)
599  edm::LogInfo("HcalSim") << "HCalSD: [" << it << "] " << layer0wt[it];
600 
601 }
602 
604  G4ParticleTable * theParticleTable = G4ParticleTable::GetParticleTable();
605  G4String particleName;
606  mumPDG = theParticleTable->FindParticle(particleName="mu-")->GetPDGEncoding();
607  mupPDG = theParticleTable->FindParticle(particleName="mu+")->GetPDGEncoding();
608 #ifdef DebugLog
609  LogDebug("HcalSim") << "HCalSD: Particle code for mu- = " << mumPDG
610  << " for mu+ = " << mupPDG;
611 #endif
612  if (showerLibrary) showerLibrary->initRun(theParticleTable,hcalConstants);
613  if (showerParam) showerParam->initRun(theParticleTable,hcalConstants);
614  if (hfshower) hfshower->initRun(theParticleTable,hcalConstants);
615  if (showerPMT) showerPMT->initRun(theParticleTable,hcalConstants);
616  if (showerBundle) showerBundle->initRun(theParticleTable,hcalConstants);
617 }
618 
619 bool HCalSD::filterHit(CaloG4Hit* aHit, double time) {
620  double threshold=0;
621  DetId theId(aHit->getUnitID());
622  switch (theId.subdetId()) {
623  case HcalBarrel:
624  threshold = eminHitHB; break;
625  case HcalEndcap:
626  threshold = eminHitHE; break;
627  case HcalOuter:
628  threshold = eminHitHO; break;
629  case HcalForward:
630  threshold = eminHitHF; break;
631  default:
632  break;
633  }
634  return ((time <= tmaxHit) && (aHit->getEnergyDeposit() > threshold));
635 }
636 
637 uint32_t HCalSD::setDetUnitId (int det, const G4ThreeVector& pos, int depth, int lay=1) {
638  uint32_t id = 0;
639  if (numberingFromDDD) {
640  //get the ID's as eta, phi, depth, ... indices
641  HcalNumberingFromDDD::HcalID tmp = numberingFromDDD->unitID(det, pos, depth, lay);
642  modifyDepth(tmp);
643  //get the ID
644  if (numberingScheme) id = numberingScheme->getUnitID(tmp);
645  }
646  return id;
647 }
648 
649 std::vector<double> HCalSD::getDDDArray(const std::string & str,
650  const DDsvalues_type & sv) {
651 #ifdef DebugLog
652  LogDebug("HcalSim") << "HCalSD:getDDDArray called for " << str;
653 #endif
654  DDValue value(str);
655  if (DDfetch(&sv,value)) {
656 #ifdef DebugLog
657  LogDebug("HcalSim") << value;
658 #endif
659  const std::vector<double> & fvec = value.doubles();
660  int nval = fvec.size();
661  if (nval < 1) {
662  edm::LogError("HcalSim") << "HCalSD : # of " << str << " bins " << nval
663  << " < 2 ==> illegal";
664  throw cms::Exception("Unknown", "HCalSD") << "nval < 2 for array " << str << "\n";
665  }
666 
667  return fvec;
668  } else {
669  edm::LogError("HcalSim") << "HCalSD : cannot get array " << str;
670  throw cms::Exception("Unknown", "HCalSD") << "cannot get array " << str << "\n";
671  }
672 }
673 
674 std::vector<G4String> HCalSD::getNames(DDFilteredView& fv) {
675 
676  std::vector<G4String> tmp;
677  bool dodet = fv.firstChild();
678  while (dodet) {
679  const DDLogicalPart & log = fv.logicalPart();
680  bool ok = true;
681 
682  for (unsigned int i=0; i<tmp.size(); ++i) {
683  if (!strcmp(tmp[i].c_str(), log.name().name().c_str())) {
684  ok = false;
685  break;
686  }
687  }
688  if (ok) tmp.push_back(log.name().name());
689  dodet = fv.next();
690  }
691  return tmp;
692 }
693 
694 bool HCalSD::isItHF(G4Step * aStep) {
695  const G4VTouchable* touch = aStep->GetPreStepPoint()->GetTouchable();
696  int levels = (touch->GetHistoryDepth()) + 1;
697  for (unsigned int it=0; it < hfNames.size(); ++it) {
698  if (levels >= hfLevels[it]) {
699  G4LogicalVolume* lv = touch->GetVolume(levels-hfLevels[it])->GetLogicalVolume();
700  if (lv == hfLV[it]) return true;
701  }
702  }
703  return false;
704 }
705 
706 bool HCalSD::isItHF (G4String name) {
707  std::vector<G4String>::const_iterator it = hfNames.begin();
708  for (; it != hfNames.end(); ++it) if (name == *it) return true;
709  return false;
710 }
711 
712 bool HCalSD::isItFibre (G4LogicalVolume* lv) {
713  std::vector<G4LogicalVolume*>::const_iterator ite = fibreLV.begin();
714  for (; ite != fibreLV.end(); ++ite) if (lv == *ite) return true;
715  return false;
716 }
717 
718 bool HCalSD::isItFibre (G4String name) {
719  std::vector<G4String>::const_iterator it = fibreNames.begin();
720  for (; it != fibreNames.end(); ++it) if (name == *it) return true;
721  return false;
722 }
723 
724 bool HCalSD::isItPMT (G4LogicalVolume* lv) {
725  std::vector<G4LogicalVolume*>::const_iterator ite = pmtLV.begin();
726  for (; ite != pmtLV.end(); ++ite) if (lv == *ite) return true;
727  return false;
728 }
729 
730 bool HCalSD::isItStraightBundle (G4LogicalVolume* lv) {
731  std::vector<G4LogicalVolume*>::const_iterator ite = fibre1LV.begin();
732  for (; ite != fibre1LV.end(); ++ite) if (lv == *ite) return true;
733  return false;
734 }
735 
736 bool HCalSD::isItConicalBundle (G4LogicalVolume* lv) {
737  std::vector<G4LogicalVolume*>::const_iterator ite = fibre2LV.begin();
738  for (; ite != fibre2LV.end(); ++ite) if (lv == *ite) return true;
739  return false;
740 }
741 
742 bool HCalSD::isItScintillator (G4Material* mat) {
743  std::vector<G4Material*>::const_iterator ite = materials.begin();
744  for (; ite != materials.end(); ++ite) if (mat == *ite) return true;
745  return false;
746 }
747 
748 bool HCalSD::isItinFidVolume (G4ThreeVector& hitPoint) {
749  bool flag = true;
750  if (applyFidCut) {
751  int npmt = HFFibreFiducial:: PMTNumber(hitPoint);
752 #ifdef DebugLog
753  edm::LogInfo("HcalSim") << "HCalSD::isItinFidVolume:#PMT= " << npmt
754  << " for hit point " << hitPoint;
755 #endif
756  if (npmt <= 0) flag = false;
757  }
758 #ifdef DebugLog
759  edm::LogInfo("HcalSim") << "HCalSD::isItinFidVolume: point " << hitPoint
760  << " return flag " << flag;
761 #endif
762  return flag;
763 }
764 
765 void HCalSD::getFromLibrary (G4Step* aStep, double weight) {
766  preStepPoint = aStep->GetPreStepPoint();
767  theTrack = aStep->GetTrack();
768  int det = 5;
769  bool ok;
770 
771  std::vector<HFShowerLibrary::Hit> hits = showerLibrary->getHits(aStep, ok, weight, false);
772 
773  double etrack = preStepPoint->GetKineticEnergy();
774  int primaryID = setTrackID(aStep);
775 
776  // Reset entry point for new primary
777  posGlobal = preStepPoint->GetPosition();
778  resetForNewPrimary(posGlobal, etrack);
779 
780  G4int particleCode = theTrack->GetDefinition()->GetPDGEncoding();
781  if (particleCode==emPDG || particleCode==epPDG || particleCode==gammaPDG) {
782  edepositEM = 1.*GeV;
783  edepositHAD = 0.;
784  } else {
785  edepositEM = 0.;
786  edepositHAD = 1.*GeV;
787  }
788 #ifdef DebugLog
789  edm::LogInfo("HcalSim") << "HCalSD::getFromLibrary " <<hits.size()
790  << " hits for " << GetName() << " of " << primaryID
791  << " with " << theTrack->GetDefinition()->GetParticleName()
792  << " of " << preStepPoint->GetKineticEnergy()/GeV << " GeV";
793 #endif
794  for (unsigned int i=0; i<hits.size(); ++i) {
795  G4ThreeVector hitPoint = hits[i].position;
796  if (isItinFidVolume (hitPoint)) {
797  int depth = hits[i].depth;
798  double time = hits[i].time;
799  unsigned int unitID = setDetUnitId(det, hitPoint, depth);
800  currentID.setID(unitID, time, primaryID, 0);
801 #ifdef plotDebug
802  plotProfile(aStep, hitPoint, 1.0*GeV, time, depth);
803  bool emType = false;
804  if (particleCode==emPDG || particleCode==epPDG || particleCode==gammaPDG)
805  emType = true;
806  plotHF(hitPoint,emType);
807 #endif
808 
809  // check if it is in the same unit and timeslice as the previous one
810  if (currentID == previousID) {
812  } else {
813  if (!checkHit()) currentHit = createNewHit();
814  }
815  }
816  }
817 
818  //Now kill the current track
819  if (ok) {
820  theTrack->SetTrackStatus(fStopAndKill);
821  G4TrackVector tv = *(aStep->GetSecondary());
822  for (unsigned int kk=0; kk<tv.size(); ++kk)
823  if (tv[kk]->GetVolume() == preStepPoint->GetPhysicalVolume())
824  tv[kk]->SetTrackStatus(fStopAndKill);
825  }
826 }
827 
828 void HCalSD::hitForFibre (G4Step* aStep, double weight) { // if not ParamShower
829 
830  preStepPoint = aStep->GetPreStepPoint();
831  theTrack = aStep->GetTrack();
832  int primaryID = setTrackID(aStep);
833 
834  int det = 5;
835  std::vector<HFShower::Hit> hits = hfshower->getHits(aStep, weight);
836 
837  G4int particleCode = theTrack->GetDefinition()->GetPDGEncoding();
838  if (particleCode==emPDG || particleCode==epPDG || particleCode==gammaPDG) {
839  edepositEM = 1.*GeV;
840  edepositHAD = 0.;
841  } else {
842  edepositEM = 0.;
843  edepositHAD = 1.*GeV;
844  }
845 
846 #ifdef DebugLog
847  edm::LogInfo("HcalSim") << "HCalSD::hitForFibre " << hits.size()
848  << " hits for " << GetName() << " of " << primaryID
849  << " with " << theTrack->GetDefinition()->GetParticleName()
850  << " of " << preStepPoint->GetKineticEnergy()/GeV
851  << " GeV in detector type " << det;
852 #endif
853  if (hits.size() > 0) {
854  for (unsigned int i=0; i<hits.size(); ++i) {
855  G4ThreeVector hitPoint = hits[i].position;
856  if (isItinFidVolume (hitPoint)) {
857  int depth = hits[i].depth;
858  double time = hits[i].time;
859  unsigned int unitID = setDetUnitId(det, hitPoint, depth);
860  currentID.setID(unitID, time, primaryID, 0);
861 #ifdef plotDebug
862  plotProfile(aStep, hitPoint, edepositEM, time, depth);
863  bool emType = false;
864  if (particleCode==emPDG || particleCode==epPDG || particleCode==gammaPDG)
865  emType = true;
866  plotHF(hitPoint,emType);
867 #endif
868  // check if it is in the same unit and timeslice as the previous one
869  if (currentID == previousID) {
871  } else {
872  posGlobal = preStepPoint->GetPosition();
873  if (!checkHit()) currentHit = createNewHit();
874  }
875  }
876  }
877  }
878 }
879 
880 void HCalSD::getFromParam (G4Step* aStep, double weight) {
881  std::vector<HFShowerParam::Hit> hits = showerParam->getHits(aStep, weight);
882  int nHit = static_cast<int>(hits.size());
883 
884  if (nHit > 0) {
885  preStepPoint = aStep->GetPreStepPoint();
886  int primaryID = setTrackID(aStep);
887 
888  int det = 5;
889 #ifdef DebugLog
890  edm::LogInfo("HcalSim") << "HCalSD::getFromParam " << nHit << " hits for "
891  << GetName() << " of " << primaryID << " with "
892  << aStep->GetTrack()->GetDefinition()->GetParticleName()
893  << " of " << preStepPoint->GetKineticEnergy()/GeV
894  << " GeV in detector type " << det;
895 #endif
896  for (int i = 0; i<nHit; ++i) {
897  G4ThreeVector hitPoint = hits[i].position;
898  int depth = hits[i].depth;
899  double time = hits[i].time;
900  unsigned int unitID = setDetUnitId(det, hitPoint, depth);
901  currentID.setID(unitID, time, primaryID, 0);
902  edepositEM = hits[i].edep*GeV;
903  edepositHAD = 0.;
904 #ifdef plotDebug
905  plotProfile(aStep, hitPoint, edepositEM, time, depth);
906 #endif
907 
908  // check if it is in the same unit and timeslice as the previous one
909  if (currentID == previousID) {
911  } else {
912  posGlobal = preStepPoint->GetPosition();
913  if (!checkHit()) currentHit = createNewHit();
914  }
915  }
916  }
917 }
918 
919 void HCalSD::getHitPMT (G4Step * aStep) {
920 
921  preStepPoint = aStep->GetPreStepPoint();
922  theTrack = aStep->GetTrack();
923  double edep = showerPMT->getHits(aStep);
924 
925  if (edep >= 0) {
926  double etrack = preStepPoint->GetKineticEnergy();
927  int primaryID = 0;
928  if (etrack >= energyCut) {
929  primaryID = theTrack->GetTrackID();
930  } else {
931  primaryID = theTrack->GetParentID();
932  if (primaryID == 0) primaryID = theTrack->GetTrackID();
933  }
934  // Reset entry point for new primary
935  posGlobal = preStepPoint->GetPosition();
936  resetForNewPrimary(posGlobal, etrack);
937 
938  //
939  int det = static_cast<int>(HcalForward);
940  G4ThreeVector hitPoint = preStepPoint->GetPosition();
941  double rr = (hitPoint.x()*hitPoint.x() + hitPoint.y()*hitPoint.y());
942  double phi = (rr == 0. ? 0. :atan2(hitPoint.y(),hitPoint.x()));
943  double etaR = showerPMT->getRadius();
944  int depth = 1;
945  if (etaR < 0) {
946  depth = 2;
947  etaR =-etaR;
948  }
949  if (hitPoint.z() < 0) etaR =-etaR;
950 #ifdef DebugLog
951  edm::LogInfo("HcalSim") << "HCalSD::Hit for Detector " << det << " etaR "
952  << etaR << " phi " << phi/deg << " depth " <<depth;
953 #endif
954  double time = (aStep->GetPostStepPoint()->GetGlobalTime());
955  uint32_t unitID = 0;
956  if (numberingFromDDD) {
958  depth,1);
959  modifyDepth(tmp);
960  if (numberingScheme) unitID = numberingScheme->getUnitID(tmp);
961  }
962  currentID.setID(unitID, time, primaryID, 1);
963 
964  edepositHAD = aStep->GetTotalEnergyDeposit();
965  edepositEM =-edepositHAD + (edep*GeV);
966 #ifdef plotDebug
967  plotProfile(aStep, hitPoint, edep*GeV, time, depth);
968 #endif
969 #ifdef DebugLog
970  double beta = preStepPoint->GetBeta();
971  LogDebug("HcalSim") << "HCalSD::getHitPMT 1 hit for " << GetName()
972  << " of " << primaryID << " with "
973  << theTrack->GetDefinition()->GetParticleName()
974  << " of " << preStepPoint->GetKineticEnergy()/GeV
975  << " GeV with velocity " << beta << " UnitID "
976  << std::hex << unitID << std::dec;
977 #endif
978  // check if it is in the same unit and timeslice as the previous one
979  if (currentID == previousID) {
981  } else {
982  if (!checkHit()) currentHit = createNewHit();
983  }
984  }
985 }
986 
987 void HCalSD::getHitFibreBundle (G4Step* aStep, bool type) {
988  preStepPoint = aStep->GetPreStepPoint();
989  theTrack = aStep->GetTrack();
990  double edep = showerBundle->getHits(aStep, type);
991 
992  if (edep >= 0) {
993  double etrack = preStepPoint->GetKineticEnergy();
994  int primaryID = 0;
995  if (etrack >= energyCut) {
996  primaryID = theTrack->GetTrackID();
997  } else {
998  primaryID = theTrack->GetParentID();
999  if (primaryID == 0) primaryID = theTrack->GetTrackID();
1000  }
1001  // Reset entry point for new primary
1002  posGlobal = preStepPoint->GetPosition();
1003  resetForNewPrimary(posGlobal, etrack);
1004 
1005  //
1006  int det = static_cast<int>(HcalForward);
1007  G4ThreeVector hitPoint = preStepPoint->GetPosition();
1008  double rr = (hitPoint.x()*hitPoint.x() + hitPoint.y()*hitPoint.y());
1009  double phi = (rr == 0. ? 0. :atan2(hitPoint.y(),hitPoint.x()));
1010  double etaR = showerBundle->getRadius();
1011  int depth = 1;
1012  if (etaR < 0) {
1013  depth = 2;
1014  etaR =-etaR;
1015  }
1016  if (hitPoint.z() < 0) etaR =-etaR;
1017 #ifdef DebugLog
1018  LogDebug("HcalSim") << "HCalSD::Hit for Detector " << det << " etaR "
1019  << etaR << " phi " << phi/deg << " depth " <<depth;
1020 #endif
1021  double time = (aStep->GetPostStepPoint()->GetGlobalTime());
1022  uint32_t unitID = 0;
1023  if (numberingFromDDD) {
1024  HcalNumberingFromDDD::HcalID tmp = numberingFromDDD->unitID(det,etaR,phi,depth,1);
1025  modifyDepth(tmp);
1026  if (numberingScheme) unitID = numberingScheme->getUnitID(tmp);
1027  }
1028  if (type) currentID.setID(unitID, time, primaryID, 3);
1029  else currentID.setID(unitID, time, primaryID, 2);
1030 
1031  edepositHAD = aStep->GetTotalEnergyDeposit();
1032  edepositEM =-edepositHAD + (edep*GeV);
1033 #ifdef plotDebug
1034  plotProfile(aStep, hitPoint, edep*GeV, time, depth);
1035 #endif
1036 #ifdef DebugLog
1037  double beta = preStepPoint->GetBeta();
1038  LogDebug("HcalSim") << "HCalSD::getHitFibreBundle 1 hit for " << GetName()
1039  << " of " << primaryID << " with "
1040  << theTrack->GetDefinition()->GetParticleName()
1041  << " of " << preStepPoint->GetKineticEnergy()/GeV
1042  << " GeV with velocity " << beta << " UnitID "
1043  << std::hex << unitID << std::dec;
1044 #endif
1045  // check if it is in the same unit and timeslice as the previous one
1047  else if (!checkHit()) currentHit = createNewHit();
1048  } // non-zero energy deposit
1049 }
1050 
1051 int HCalSD::setTrackID (G4Step* aStep) {
1052  theTrack = aStep->GetTrack();
1053 
1054  double etrack = preStepPoint->GetKineticEnergy();
1055  TrackInformation * trkInfo = (TrackInformation *)(theTrack->GetUserInformation());
1056  int primaryID = trkInfo->getIDonCaloSurface();
1057  if (primaryID == 0) {
1058 #ifdef DebugLog
1059  edm::LogInfo("HcalSim") << "HCalSD: Problem with primaryID **** set by "
1060  << "force to TkID **** " <<theTrack->GetTrackID();
1061 #endif
1062  primaryID = theTrack->GetTrackID();
1063  }
1064 
1065  if (primaryID != previousID.trackID())
1066  resetForNewPrimary(preStepPoint->GetPosition(), etrack);
1067 
1068  return primaryID;
1069 }
1070 
1072 
1073  std::ifstream infile;
1074  int entry=0;
1075  infile.open(fName.c_str(), std::ios::in);
1076  if (infile) {
1077  int det, zside, etaR, phi, lay;
1078  double wt;
1079  while (infile >> det >> zside >> etaR >> phi >> lay >> wt) {
1080  uint32_t id = HcalTestNumbering::packHcalIndex(det,zside,1,etaR,phi,lay);
1081  layerWeights.insert(std::pair<uint32_t,double>(id,wt));
1082  ++entry;
1083 #ifdef DebugLog
1084  edm::LogInfo("HcalSim") << "HCalSD::readWeightFromFile:Entry " << entry
1085  << " ID " << std::hex << id << std::dec << " ("
1086  << det << "/" << zside << "/1/" << etaR << "/"
1087  << phi << "/" << lay << ") Weight " << wt;
1088 #endif
1089  }
1090  infile.close();
1091  }
1092  edm::LogInfo("HcalSim") << "HCalSD::readWeightFromFile: reads " << entry
1093  << " weights from " << fName;
1094  if (entry <= 0) useLayerWt = false;
1095 }
1096 
1097 double HCalSD::layerWeight(int det, const G4ThreeVector& pos, int depth, int lay) {
1098 
1099  double wt = 1.;
1100  if (numberingFromDDD) {
1101  //get the ID's as eta, phi, depth, ... indices
1103  depth, lay);
1104  modifyDepth(tmp);
1105  uint32_t id = HcalTestNumbering::packHcalIndex(tmp.subdet, tmp.zside, 1,
1106  tmp.etaR, tmp.phis,tmp.lay);
1107  std::map<uint32_t,double>::const_iterator ite = layerWeights.find(id);
1108  if (ite != layerWeights.end()) wt = ite->second;
1109 #ifdef DebugLog
1110  edm::LogInfo("HcalSim") << "HCalSD::layerWeight: ID " << std::hex << id
1111  << std::dec << " (" << tmp.subdet << "/"
1112  << tmp.zside << "/1/" << tmp.etaR << "/"
1113  << tmp.phis << "/" << tmp.lay << ") Weight " <<wt;
1114 #endif
1115  }
1116  return wt;
1117 }
1118 
1119 void HCalSD::plotProfile(G4Step* aStep,const G4ThreeVector& global, double edep,
1120  double time, int id) {
1121 
1122  const G4VTouchable* touch = aStep->GetPreStepPoint()->GetTouchable();
1123  static const G4String modName[8] = {"HEModule", "HVQF" , "HBModule", "MBAT",
1124  "MBBT" , "MBBTC", "MBBT_R1P", "MBBT_R1M"};
1125  G4ThreeVector local;
1126  bool found=false;
1127  double depth=-2000;
1128  int idx = 4;
1129  for (int n=0; n<touch->GetHistoryDepth(); ++n) {
1130  G4String name = touch->GetVolume(n)->GetName();
1131 #ifdef DebugLog
1132  LogDebug("HcalSim") << "plotProfile Depth " << n << " Name " << name;
1133 #endif
1134  for (unsigned int ii=0; ii<8; ++ii) {
1135  if (name == modName[ii]) {
1136  found = true;
1137  int dn = touch->GetHistoryDepth() - n;
1138  local = touch->GetHistory()->GetTransform(dn).TransformPoint(global);
1139  if (ii == 0) {depth = local.z() - 4006.5; idx = 1;}
1140  else if (ii == 1) {depth = local.z() + 825.0; idx = 3;}
1141  else if (ii == 2) {depth = local.x() - 1775.; idx = 0;}
1142  else {depth = local.y() + 15.; idx = 2;}
1143  break;
1144  }
1145  }
1146  if (found) break;
1147  }
1148  if (!found) depth = std::abs(global.z()) - 11500;
1149 #ifdef DebugLog
1150  LogDebug("HcalSim") << "plotProfile Found " << found << " Global " << global
1151  << " Local " << local << " depth " << depth << " ID "
1152  << id << " EDEP " << edep << " Time " << time;
1153 #endif
1154  if (hit_[idx] != 0) hit_[idx]->Fill(edep);
1155  if (time_[idx] != 0) time_[idx]->Fill(time,edep);
1156  if (dist_[idx] != 0) dist_[idx]->Fill(depth,edep);
1157  int jd = 2*idx + id - 7;
1158  if (jd >= 0 && jd < 4) {
1159  jd += 5;
1160  if (hit_[jd] != 0) hit_[jd]->Fill(edep);
1161  if (time_[jd] != 0) time_[jd]->Fill(time,edep);
1162  if (dist_[jd] != 0) dist_[jd]->Fill(depth,edep);
1163  }
1164 }
1165 
1166 void HCalSD::plotHF(G4ThreeVector& hitPoint, bool emType) {
1167  double zv = std::abs(hitPoint.z()) - gpar[4];
1168  if (emType) {
1169  if (hzvem != 0) hzvem->Fill(zv);
1170  } else {
1171  if (hzvhad != 0) hzvhad->Fill(zv);
1172  }
1173 }
1174 
1176  if (id.subdet == 4) {
1177  int ieta = (id.zside == 0) ? -id.etaR : id.etaR;
1178  if (hcalConstants->maxHFDepth(ieta,id.phis) > 2) {
1179  if (id.depth <= 2) {
1180  if (G4UniformRand() > 0.5) id.depth += 2;
1181  }
1182  }
1183  }
1184 }
#define LogDebug(id)
float edepositEM
Definition: CaloSD.h:121
const double beta
double energyCut
Definition: CaloSD.h:123
HCalSD(G4String, const DDCompactView &, const SensitiveDetectorCatalog &, edm::ParameterSet const &, const SimTrackManager *)
Definition: HCalSD.cc:42
type
Definition: HCALResponse.h:21
T getParameter(std::string const &) const
std::vector< double > layer0wt
Definition: HCalSD.h:97
T getUntrackedParameter(std::string const &, T const &) const
int i
Definition: DBlmapReader.cc:9
bool useParam
Definition: HCalSD.h:93
double eminHitHE
Definition: HCalSD.h:94
HFShowerParam * showerParam
Definition: HCalSD.h:86
TH1F * time_[9]
Definition: HCalSD.h:103
G4int emPDG
Definition: CaloSD.h:136
double getRadius()
Definition: HFShowerPMT.cc:137
const DDLogicalPart & logicalPart() const
The logical-part of the current node in the filtered-view.
const std::vector< double > & doubles() const
a reference to the double-valued values stored in the given instance of DDValue
Definition: DDValue.cc:137
const double GeV
Definition: MathUtil.h:16
double kmaxNeutron
Definition: CaloSD.h:134
void updateHit(CaloG4Hit *)
Definition: CaloSD.cc:440
void hitForFibre(G4Step *step, double weight)
Definition: HCalSD.cc:828
const N & name() const
Definition: DDBase.h:78
void getFromParam(G4Step *step, double weight)
Definition: HCalSD.cc:880
int getIDonCaloSurface() const
bool useLayerWt
Definition: HCalSD.h:91
Definition: CaloSD.h:42
void addFilter(const DDFilter &, DDLogOp op=DDLogOp::AND)
virtual void update(const BeginOfJob *)
This routine will be called when the appropriate signal arrives.
Definition: HCalSD.cc:572
bool isItStraightBundle(G4LogicalVolume *)
Definition: HCalSD.cc:730
double dose(unsigned int layer, double radius)
Definition: HFDarkening.cc:34
virtual bool ProcessHits(G4Step *, G4TouchableHistory *)
Definition: HCalSD.cc:371
std::vector< double > gpar
Definition: HCalSD.h:97
bool useFibreBundle
Definition: HCalSD.h:91
bool isItinFidVolume(G4ThreeVector &)
Definition: HCalSD.cc:748
double betaThr
Definition: HCalSD.h:92
void initRun(G4ParticleTable *, HcalDDDSimConstants *)
Definition: HFShower.cc:454
double deliveredLumi
Definition: HCalSD.h:95
std::vector< Hit > getHits(G4Step *aStep, bool &ok, double weight, bool onlyLong=false)
virtual uint32_t getUnitID(const HcalNumberingFromDDD::HcalID &id)
HFShowerFibreBundle * showerBundle
Definition: HCalSD.h:88
std::vector< G4LogicalVolume * > fibre1LV
Definition: HCalSD.h:101
std::vector< G4LogicalVolume * > fibreLV
Definition: HCalSD.h:101
double eminHitHB
Definition: HCalSD.h:94
bool useShowerLibrary
Definition: HCalSD.h:93
std::vector< double > getDDDArray(const std::string &, const DDsvalues_type &)
Definition: HCalSD.cc:649
int getMaxDepth(const int type) const
double getHits(G4Step *aStep, bool type)
#define NULL
Definition: scimark2.h:8
virtual uint32_t setDetUnitId(G4Step *step)
Definition: HCalSD.cc:551
double birk2
Definition: HCalSD.h:92
int setTrackID(G4Step *step)
Definition: HCalSD.cc:1051
void getFromLibrary(G4Step *step, double weight)
Definition: HCalSD.cc:765
bool usePMTHit
Definition: HCalSD.h:91
#define DebugLog
G4ThreeVector posGlobal
Definition: CaloSD.h:113
int zside(DetId const &)
static const unsigned int numberOfZLayers
Definition: HFDarkening.h:26
void modifyDepth(HcalNumberingFromDDD::HcalID &id)
Definition: HCalSD.cc:1175
int ii
Definition: cuy.py:588
void setNumberingScheme(HcalNumberingScheme *)
Definition: HCalSD.cc:564
type of data representation of DDCompactView
Definition: DDCompactView.h:90
double birk1
Definition: HCalSD.h:92
double kmaxProton
Definition: CaloSD.h:134
bool DDfetch(const DDsvalues_type *, DDValue &)
helper for retrieving DDValues from DDsvalues_type *.
Definition: DDsvalues.cc:80
double degradation(double mrad)
Definition: HFDarkening.cc:62
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
static int PMTNumber(const G4ThreeVector &pe_effect)
bool isItHF(G4Step *)
Definition: HCalSD.cc:694
G4bool checkHit()
Definition: CaloSD.cc:331
static TrackerG4SimHitNumberingScheme & numberingScheme(const DDCompactView &cpv, const GeometricDet &det)
TH1F * hzvhad
Definition: HCalSD.h:103
void initRun(G4ParticleTable *, HcalDDDSimConstants *)
Definition: HFShowerPMT.cc:80
double int_lumi(double intlumi)
Definition: HFDarkening.cc:66
double eminHitHF
Definition: HCalSD.h:94
const double MeV
bool isItConicalBundle(G4LogicalVolume *)
Definition: HCalSD.cc:736
static uint32_t packHcalIndex(int det, int z, int depth, int eta, int phi, int lay)
TH1F * hit_[9]
Definition: HCalSD.h:103
const std::vector< double > & getLayer0Wt() const
void resetForNewPrimary(const G4ThreeVector &, double)
Definition: CaloSD.cc:454
virtual void initRun()
Definition: HCalSD.cc:603
bool testNumber
Definition: HCalSD.h:91
std::vector< G4LogicalVolume * > pmtLV
Definition: HCalSD.h:101
std::vector< G4LogicalVolume * > hfLV
Definition: HCalSD.h:101
double kmaxIon
Definition: CaloSD.h:134
bool suppressHeavy
Definition: CaloSD.h:132
bool isItScintillator(G4Material *)
Definition: HCalSD.cc:742
bool next()
set current node to the next node in the filtered tree
HFShower * hfshower
Definition: HCalSD.h:85
bool useBirk
Definition: HCalSD.h:91
float edepositHAD
Definition: CaloSD.h:121
double birk3
Definition: HCalSD.h:92
int trackID() const
Definition: CaloHitID.h:25
virtual double getEnergyDeposit(G4Step *)
Definition: HCalSD.cc:475
G4int epPDG
Definition: CaloSD.h:136
void plotHF(G4ThreeVector &pos, bool emType)
Definition: HCalSD.cc:1166
std::vector< std::pair< unsigned int, DDValue > > DDsvalues_type
std::maps an index to a DDValue. The index corresponds to the index assigned to the name of the std::...
Definition: DDsvalues.h:20
G4int gammaPDG
Definition: CaloSD.h:136
bool isAvailable() const
Definition: Service.h:46
bool applyFidCut
Definition: HCalSD.h:93
std::vector< Hit > getHits(G4Step *aStep, double weight)
Definition: HFShower.cc:47
TH1F * dist_[9]
Definition: HCalSD.h:103
virtual ~HCalSD()
Definition: HCalSD.cc:358
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
static void unpackHcalIndex(const uint32_t &idx, int &det, int &z, int &depth, int &eta, int &phi, int &lay)
A DDLogicalPart aggregates information concerning material, solid and sensitveness ...
Definition: DDLogicalPart.h:92
HcalNumberingScheme * numberingScheme
Definition: HCalSD.h:83
void getHitPMT(G4Step *step)
Definition: HCalSD.cc:919
T * make(const Args &...args) const
make new ROOT object
int getNumberOfHits()
Definition: CaloSD.cc:361
HFDarkening * m_HFDarkening
Definition: HCalSD.h:90
CaloHitID previousID
Definition: CaloSD.h:117
double getAttenuation(G4Step *aStep, double birk1, double birk2, double birk3)
Definition: CaloSD.cc:465
CaloG4Hit * currentHit
Definition: CaloSD.h:128
std::vector< int > hfLevels
Definition: HCalSD.h:98
virtual std::vector< std::string > getNames()
void plotProfile(G4Step *step, const G4ThreeVector &pos, double edep, double time, int id)
Definition: HCalSD.cc:1119
void initRun(G4ParticleTable *, HcalDDDSimConstants *)
HEDarkening * m_HEDarkening
Definition: HCalSD.h:89
void NaNTrap(G4Step *step)
G4Track * theTrack
Definition: CaloSD.h:118
virtual G4bool getStepInfo(G4Step *aStep)
Definition: CaloSD.cc:250
bool isItPMT(G4LogicalVolume *)
Definition: HCalSD.cc:724
G4int mupPDG
Definition: HCalSD.h:96
double eminHitHO
Definition: HCalSD.h:94
double tmaxHit
Definition: CaloSD.h:123
int ietaAbs() const
get the absolute value of the cell ieta
Definition: HcalDetId.cc:98
void setID(uint32_t unitID, double timeSlice, int trackID, uint16_t depth=0)
Definition: CaloHitID.cc:44
TH1F * hzvem
Definition: HCalSD.h:103
G4StepPoint * preStepPoint
Definition: CaloSD.h:120
const std::vector< double > & getGparHF() const
Definition: DetId.h:18
static const unsigned int lowZLimit
Definition: HFDarkening.h:29
static const G4LogicalVolume * GetVolume(const std::string &name)
TFileDirectory mkdir(const std::string &dir, const std::string &descr="")
create a new subdirectory
Definition: TFileService.h:69
CaloHitID currentID
Definition: CaloSD.h:117
std::vector< Hit > getHits(G4Step *aStep, double weight)
static const unsigned int upperZLimit
Definition: HFDarkening.h:30
void readWeightFromFile(std::string)
Definition: HCalSD.cc:1071
void initRun(G4ParticleTable *, HcalDDDSimConstants *)
void getHitFibreBundle(G4Step *step, bool type)
Definition: HCalSD.cc:987
const T & get() const
Definition: EventSetup.h:56
int ke
bool isPrimary() const
DDsvalues_type mergedSpecifics() const
double getHits(G4Step *aStep)
Definition: HFShowerPMT.cc:91
HcalNumberingFromDDD * numberingFromDDD
Definition: HCalSD.h:82
double layerWeight(int, const G4ThreeVector &, int, int)
Definition: HCalSD.cc:1097
std::vector< std::vector< double > > tmp
Definition: MVATrainer.cc:100
double getResponseWt(G4Track *)
Definition: CaloSD.cc:607
std::vector< G4String > fibreNames
Definition: HCalSD.h:99
G4bool hitExists()
Definition: CaloSD.cc:310
bool firstChild()
set the current node to the first child ...
std::vector< G4Material * > materials
Definition: HCalSD.h:100
virtual bool filterHit(CaloG4Hit *, double)
Definition: HCalSD.cc:619
list entry
Definition: mps_splice.py:62
std::vector< G4String > hfNames
Definition: HCalSD.h:99
G4int mumPDG
Definition: HCalSD.h:96
std::map< uint32_t, double > layerWeights
Definition: HCalSD.h:102
tuple level
Definition: testEve_cfg.py:34
tuple tfile
Definition: compare.py:321
HFShowerPMT * showerPMT
Definition: HCalSD.h:87
uint32_t getUnitID() const
Definition: CaloG4Hit.h:69
int weight
Definition: histoStyle.py:50
HcalID unitID(int det, const CLHEP::Hep3Vector &pos, int depth, int lay=-1) const
float degradation(float intlumi, int ieta, int lay)
Definition: HEDarkening.cc:52
HFShowerLibrary * showerLibrary
Definition: HCalSD.h:84
void initRun(G4ParticleTable *, HcalDDDSimConstants *)
std::vector< G4LogicalVolume * > fibre2LV
Definition: HCalSD.h:101
const std::string & name() const
Returns the name.
Definition: DDName.cc:90
const DDMaterial & material(void) const
Returns a reference object of the material this LogicalPart is made of.
void setCriteria(const DDValue &nameVal, DDCompOp, DDLogOp l=DDLogOp::AND, bool asString=true, bool merged=true)
Definition: DDFilter.cc:253
CaloG4Hit * createNewHit()
Definition: CaloSD.cc:363
std::vector< G4String > matNames
Definition: HCalSD.h:99
bool isItFibre(G4LogicalVolume *)
Definition: HCalSD.cc:712
double getEnergyDeposit() const
Definition: CaloG4Hit.h:81
bool useHF
Definition: HCalSD.h:93
int maxHFDepth(int ieta, int iphi) const
HcalDDDSimConstants * hcalConstants
Definition: HCalSD.h:81
The DDGenericFilter is a runtime-parametrized Filter looking on DDSpecifcs.
Definition: DDFilter.h:33