LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
LArG4Detector.cc
Go to the documentation of this file.
1 //=============================================================================
2 // LArG4Detector_service.hh:
3 // LArG4DetectorService is the service that constructs the Geant 4 Geometry
4 // as specified in a gdml file.
5 // To use this service, all you need to do is put it in the services section
6 // of the fcl configuration file, like this (Just change the name of the gdml file):
7 //
8 // <pre>
9 // services: {
10 // ...
11 // ...
12 // LArG4Detector :
13 // {
14 // category: "world"
15 // gdmlFileName_ : "ta_target.gdml"
16 // }
17 // }
18 // </pre>
19 // Author: Hans Wenzel (Fermilab)
20 // Modified: David Rivera
21 //=============================================================================
22 
23 // framework includes:
25 #include "cetlib/search_path.h"
26 // larg4 includes:
31 // artg4tk includes:
32 #include "artg4tk/pluginDetectors/gdml/ByParticle.hh"
33 #include "artg4tk/pluginDetectors/gdml/CalorimeterHit.hh"
34 #include "artg4tk/pluginDetectors/gdml/CalorimeterSD.hh"
35 #include "artg4tk/pluginDetectors/gdml/ColorReader.hh"
36 #include "artg4tk/pluginDetectors/gdml/DRCalorimeterHit.hh"
37 #include "artg4tk/pluginDetectors/gdml/DRCalorimeterSD.hh"
38 #include "artg4tk/pluginDetectors/gdml/HadIntAndEdepTrkSD.hh"
39 #include "artg4tk/pluginDetectors/gdml/HadInteractionSD.hh"
40 #include "artg4tk/pluginDetectors/gdml/PhotonHit.hh"
41 #include "artg4tk/pluginDetectors/gdml/PhotonSD.hh"
42 #include "artg4tk/pluginDetectors/gdml/TrackerHit.hh"
43 #include "artg4tk/pluginDetectors/gdml/TrackerSD.hh"
44 //lardataobj includes:
47 // Geant 4 includes:
48 #include "Geant4/G4AutoDelete.hh"
49 #include "Geant4/G4GDMLParser.hh"
50 #include "Geant4/G4LogicalVolume.hh"
51 #include "Geant4/G4LogicalVolumeStore.hh"
52 #include "Geant4/G4PhysicalVolumeStore.hh"
53 #include "Geant4/G4RegionStore.hh"
54 #include "Geant4/G4SDManager.hh"
55 #include "Geant4/G4StepLimiter.hh"
56 #include "Geant4/G4Types.hh"
57 #include "Geant4/G4UnitsTable.hh"
58 #include "Geant4/G4UserLimits.hh"
59 #include "Geant4/G4VPhysicalVolume.hh"
60 #include "Geant4/G4VUserDetectorConstruction.hh"
61 #include "Geant4/globals.hh"
62 
63 // C++ includes
64 #include <unordered_map>
65 
66 using std::string;
67 
68 namespace {
69  template <typename T>
70  auto make_product(T t)
71  {
72  return std::make_unique<T>(std::move(t));
73  }
74 }
75 
77  : artg4tk::DetectorBase(p,
78  p.get<string>("name", "LArG4DetectorService"),
79  p.get<string>("category", "World"),
80  p.get<string>("mother_category", ""))
81  , gdmlFileName_{p.get<std::string>("gdmlFileName_", "")}
82  , checkOverlaps_{p.get<bool>("CheckOverlaps", false)}
83  , updateSimEnergyDeposits_{p.get<bool>("UpdateSimEnergyDeposits", true)}
84  , updateAuxDetHits_{p.get<bool>("UpdateAuxDetHits", true)}
85  , volumeNames_{p.get<std::vector<std::string>>("volumeNames", {})}
86  , stepLimits_{p.get<std::vector<float>>("stepLimits", {})}
88  , dumpMP_{p.get<bool>("DumpMaterialProperties", false)}
89 {
90  // Make sure units are defined.
91  G4UnitDefinition::GetUnitsTable();
92 
93  // -- D.R. : Check for valid volume, steplimit pairs
94  if (inputVolumes_ != size(stepLimits_)) {
95  throw cet::exception("LArG4DetectorService") << "Configuration error: volumeNames:[] and"
96  << " stepLimits:[] have different sizes!"
97  << "\n";
98  }
99 
100  //-- define commonly used units, that we might need
101  new G4UnitDefinition("volt/cm", "V/cm", "Electric field", CLHEP::volt / CLHEP::cm);
102 
103  if (inputVolumes_ > 0) {
104  mf::LogInfo("LArG4DetectorService::Ctr")
105  << "Reading stepLimit(s) from the configuration file, for volume(s):";
106  }
107  for (size_t i = 0; i < inputVolumes_; ++i) {
108  if (stepLimits_[i] < 0) {
109  throw cet::exception("LArG4DetectorService")
110  << "Invalid stepLimits found. Step limits must be"
111  << " positive! Bad value : stepLimits[" << i << "] = " << stepLimits_.at(i) << " [mm]\n";
112  }
113 
114  overrideGDMLStepLimit_Map.emplace(volumeNames_[i], stepLimits_[i] * CLHEP::mm);
115  mf::LogInfo("LArG4DetectorService::Ctr")
116  << "Volume: " << volumeNames_[i] << ", stepLimit: " << stepLimits_[i];
117  } //--loop over inputVolumes
118 } //--Ctor
119 
120 // Destructor
121 
122 std::vector<G4LogicalVolume*> larg4::LArG4DetectorService::doBuildLVs()
123 {
124  ColorReader reader;
125  G4GDMLParser parser(&reader);
126  parser.SetOverlapCheck(checkOverlaps_);
127  cet::search_path sp{"FW_SEARCH_PATH"};
128  std::string fullGDMLFileName;
129  if (!sp.find_file(gdmlFileName_, fullGDMLFileName)) {
130  throw cet::exception("LArG4DetectorService") << "Cannot find file: " << gdmlFileName_;
131  }
132  parser.Read(fullGDMLFileName, false);
133  G4VPhysicalVolume* World = parser.GetWorldVolume();
134 
135  std::stringstream ss;
136  ss << World->GetTranslation() << "\n\n";
137  ss << "Found World: " << World->GetName() << "\n";
138  ss << "World LV: " << World->GetLogicalVolume()->GetName() << "\n";
139  G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
140  ss << "Found " << pLVStore->size() << " logical volumes."
141  << "\n\n";
142  G4PhysicalVolumeStore* pPVStore = G4PhysicalVolumeStore::GetInstance();
143  ss << "Found " << pPVStore->size() << " physical volumes."
144  << "\n\n";
145  G4SDManager* SDman = G4SDManager::GetSDMpointer();
146  const G4GDMLAuxMapType* auxmap = parser.GetAuxMap();
147  ss << "Found " << auxmap->size() << " volume(s) with auxiliary information."
148  << "\n\n";
149  ss << "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
150  mf::LogInfo("LArG4DetectorService::doBuildLVs") << ss.str();
151 
152  for (auto const& [volume, auxes] : *auxmap) {
153  G4cout << "Volume " << volume->GetName()
154  << " has the following list of auxiliary information: \n";
155  for (auto const& aux : auxes) {
156  G4cout << "--> Type: " << aux.type << " Value: " << aux.value << "\n";
157 
158  G4double value = atof(aux.value);
159  G4double val_unit = 1; //--no unit
160  G4String provided_category = "NONE";
161  if ((aux.unit) && (aux.unit != "")) { // -- if provided and non-NULL
162  val_unit = G4UnitDefinition::GetValueOf(aux.unit);
163  provided_category = G4UnitDefinition::GetCategory(aux.unit);
164  mf::LogInfo("AuxUnit") << " Unit parsed = " << aux.unit
165  << " from unit category: " << provided_category.c_str();
166  value *=
167  val_unit; //-- Now do something with the value, making sure that the unit is appropriate
168  }
169 
170  if (aux.type == "StepLimit") {
171  G4UserLimits* fStepLimit = new G4UserLimits();
172  G4AutoDelete::Register(fStepLimit);
173 
174  //-- check that steplimit has valid length unit category
175  G4String steplimit_category = "Length";
176  if (provided_category == steplimit_category) {
177  mf::LogInfo("AuxUnit") << "Valid StepLimit unit category obtained: "
178  << provided_category.c_str();
179  // -- convert length to mm
180  value = (value / CLHEP::mm) * CLHEP::mm;
181  fStepLimit->SetMaxAllowedStep(value);
182  mf::LogInfo("fStepLimit")
183  << "fStepLimit: " << value << " " << value / CLHEP::cm << " cm\n";
184  }
185  else if (provided_category ==
186  "NONE") { //--no unit category provided, use the default CLHEP::mm
187  MF_LOG_WARNING("StepLimitUnit") << "StepLimit in geometry file does not have a unit!"
188  << " Defaulting to mm...";
189  value *= CLHEP::mm;
190  fStepLimit->SetMaxAllowedStep(value);
191  mf::LogInfo("fStepLimit")
192  << "fStepLimit: " << value << " " << value / CLHEP::cm << " cm\n";
193  }
194  else { //--wrong unit category provided
195  throw cet::exception("StepLimitUnit")
196  << "StepLimit does not have a valid length unit!\n"
197  << " Category of unit provided = " << provided_category << ".\n";
198  }
199 
200  volume->SetUserLimits(fStepLimit);
201  // -- D.R. insert into map <volName,stepLimit> to cross-check later
202  MF_LOG_DEBUG("LArG4DetectorService::")
203  << "Set stepLimit for volume: " << volume->GetName() << " from the GDML file.";
204  setGDMLVolumes_.insert(std::make_pair(volume->GetName(), (float)(value / CLHEP::mm)));
205  }
206  if (aux.type == "ExcitationEnergy") {
207  G4String ExcitationEnergy_category = "Energy";
208  if (provided_category == ExcitationEnergy_category) {
209  G4cout << "Valid ExcitationEnergy unit category obtained: " << provided_category.c_str()
210  << G4endl;
211  G4cout << " unit Value:" << val_unit << " Value: " << value << G4endl;
212  G4cout << " unit Value:" << val_unit << " Value: " << value / CLHEP::eV << " eV"
213  << G4endl;
214  volume->GetMaterial()->GetIonisation()->SetMeanExcitationEnergy(value);
215  G4cout << " Mean Ionization energy: "
216  << volume->GetMaterial()->GetIonisation()->GetMeanExcitationEnergy() << G4endl;
217  }
218  }
219 
220  if (aux.type == "SensDet") {
221  if (aux.value == "DRCalorimeter") {
222  G4String name = volume->GetName() + "_DRCalorimeter";
223  artg4tk::DRCalorimeterSD* aDRCalorimeterSD = new artg4tk::DRCalorimeterSD(name);
224  SDman->AddNewDetector(aDRCalorimeterSD);
225  volume->SetSensitiveDetector(aDRCalorimeterSD);
226  std::cout << "Attaching sensitive Detector: " << aux.value
227  << " to Volume: " << volume->GetName() << "\n";
228  detectors_.emplace_back(volume->GetName(), aux.value);
229  }
230  else if (aux.value == "Calorimeter") {
231  G4String name = volume->GetName() + "_Calorimeter";
232  artg4tk::CalorimeterSD* aCalorimeterSD = new artg4tk::CalorimeterSD(name);
233  SDman->AddNewDetector(aCalorimeterSD);
234  volume->SetSensitiveDetector(aCalorimeterSD);
235  std::cout << "Attaching sensitive Detector: " << aux.value
236  << " to Volume: " << volume->GetName() << "\n";
237  detectors_.emplace_back(volume->GetName(), aux.value);
238  }
239  else if (aux.value == "PhotonDetector") {
240  G4String name = volume->GetName() + "_PhotonDetector";
241  artg4tk::PhotonSD* aPhotonSD = new artg4tk::PhotonSD(name);
242  SDman->AddNewDetector(aPhotonSD);
243  volume->SetSensitiveDetector(aPhotonSD);
244  std::cout << "Attaching sensitive Detector: " << aux.value
245  << " to Volume: " << volume->GetName() << "\n";
246  detectors_.emplace_back(volume->GetName(), aux.value);
247  }
248  else if (aux.value == "Tracker") {
249  G4String name = volume->GetName() + "_Tracker";
250  artg4tk::TrackerSD* aTrackerSD = new artg4tk::TrackerSD(name);
251  SDman->AddNewDetector(aTrackerSD);
252  volume->SetSensitiveDetector(aTrackerSD);
253  std::cout << "Attaching sensitive Detector: " << aux.value
254  << " to Volume: " << volume->GetName() << "\n";
255  detectors_.push_back(std::make_pair(volume->GetName(), aux.value));
256  }
257  else if (aux.value == "SimEnergyDeposit") {
258  G4String name = volume->GetName() + "_SimEnergyDeposit";
259  SimEnergyDepositSD* aSimEnergyDepositSD = new SimEnergyDepositSD(name);
260  SDman->AddNewDetector(aSimEnergyDepositSD);
261  volume->SetSensitiveDetector(aSimEnergyDepositSD);
262  std::cout << "Attaching sensitive Detector: " << aux.value
263  << " to Volume: " << volume->GetName() << "\n";
264  detectors_.emplace_back(volume->GetName(), aux.value);
265  }
266  else if (aux.value == "AuxDet") {
267  G4String name = volume->GetName() + "_AuxDet";
268  AuxDetSD* aAuxDetSD = new AuxDetSD(name);
269  SDman->AddNewDetector(aAuxDetSD);
270  volume->SetSensitiveDetector(aAuxDetSD);
271  std::cout << "Attaching sensitive Detector: " << aux.value
272  << " to Volume: " << volume->GetName() << "\n";
273  detectors_.emplace_back(volume->GetName(), aux.value);
274  }
275  else if (aux.value == "HadInteraction") {
276  G4String name = volume->GetName() + "_HadInteraction";
277  artg4tk::HadInteractionSD* aHadInteractionSD = new artg4tk::HadInteractionSD(name);
278  // NOTE: This will be done in the HadInteractionSD ctor
279  // SDman->AddNewDetector(aHadInteractionSD);
280  volume->SetSensitiveDetector(aHadInteractionSD);
281  std::cout << "Attaching sensitive Detector: " << aux.value
282  << " to Volume: " << volume->GetName() << "\n";
283  detectors_.emplace_back(volume->GetName(), aux.value);
284  }
285  else if (aux.value == "HadIntAndEdepTrk") {
286  G4String name = volume->GetName() + "_HadIntAndEdepTrk";
287  artg4tk::HadIntAndEdepTrkSD* aHadIntAndEdepTrkSD = new artg4tk::HadIntAndEdepTrkSD(name);
288  // NOTE: This will be done in the HadIntAndEdepTrkSD ctor
289  // SDman->AddNewDetector(aHadIntAndEdepTrkSD);
290  volume->SetSensitiveDetector(aHadIntAndEdepTrkSD);
291  std::cout << "Attaching sensitive Detector: " << aux.value
292  << " to Volume: " << volume->GetName() << "\n";
293  detectors_.emplace_back(volume->GetName(), aux.value);
294  }
295  }
296  }
297  std::cout
298  << "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
299  }
300  if (dumpMP_) { G4cout << *(G4Material::GetMaterialTable()) << G4endl; }
301  if (inputVolumes_ > 0) { setStepLimits(); }
302  std::cout << "List SD Tree: \n";
303  SDman->ListTree();
304  std::cout << " Collection Capacity: " << SDman->GetCollectionCapacity() << "\n";
305  G4HCtable* hctable = SDman->GetHCtable();
306  for (G4int j = 0; j < SDman->GetCollectionCapacity(); ++j) {
307  std::cout << "HC Name: " << hctable->GetHCname(j) << " SD Name: " << hctable->GetSDname(j)
308  << "\n";
309  }
310  std::cout << "==================================================\n";
311  // Return our logical volumes.
312  std::vector<G4LogicalVolume*> myLVvec;
313  myLVvec.push_back(pLVStore->at(0)); // only need to return the LV of the world
314  std::cout << "nr of LV ======================: " << myLVvec.size() << "\n";
315 
316  return myLVvec;
317 }
318 
319 std::vector<G4VPhysicalVolume*> larg4::LArG4DetectorService::doPlaceToPVs(
320  std::vector<G4LogicalVolume*>)
321 {
322  // Note we don't use our input.
323  std::vector<G4VPhysicalVolume*> myPVvec;
324  G4PhysicalVolumeStore* pPVStore = G4PhysicalVolumeStore::GetInstance();
325  myPVvec.push_back(pPVStore->at(
326  pPVStore->size() - 1)); // only need to return the PV of the world (last entry in Volume Store)
327  return myPVvec;
328 }
329 
331 {
332  // -- D. Rivera : This function sets step limits for volumes provided in the configuration file
333  // and overrides the step limit (if any) set for the same volumes but from the GMDL
334  // geometry file. The GDML step limit (if provided in the gdml file) is set first
335  // and later overriden by this method if a valid volumeName,setStepLimit is provided.
336  MF_LOG_WARNING("LArG4DetectorService::setStepLimits")
337  << "Setting step limits from configuration"
338  << " file. This will OVERRIDE redundant stepLimit(s) set in the GDML file. Note"
339  << " that stepLimits are only active if enabled in the physicsListService via the"
340  << " appropriate parameter.";
341 
342  std::string volumeName = "";
343  G4LogicalVolume* setVol = nullptr;
344  for (auto const& [name, newStepLimit] : overrideGDMLStepLimit_Map) {
345  G4double previousStepLimit = 0.;
346 
347  // -- Check whether the volumeName provided corresponds to a valid volumeName in the geometry
348  if (setVol = G4LogicalVolumeStore::GetInstance()->GetVolume(name, false); !setVol) {
349  throw cet::exception("invalidInputVolumeName")
350  << "Provided volume name : " << name << " not found!\n";
351  }
352 
353  // -- get the G4LogicalVolume corresponding to the selectedVolume
354  volumeName = setVol->GetName();
355  MF_LOG_DEBUG("LArG4DetectorService::setStepLimits")
356  << "Got logical volume with name: " << volumeName;
357 
358  G4UserLimits* fStepLimitOverride = new G4UserLimits();
359  G4AutoDelete::Register(fStepLimitOverride);
360 
361  // -- check if a stepLimit for this volume has been set before:
362  auto search = setGDMLVolumes_.find(volumeName);
363  if (search != setGDMLVolumes_.end()) { // -- volume name found in override list
364  previousStepLimit = (G4double)(search->second);
365  if (newStepLimit != previousStepLimit) {
366  MF_LOG_WARNING("LArG4DetectorService::setStepLimits")
367  << "OVERRIDING PREVIOUSLY SET"
368  << " STEPLIMIT FOR VOLUME : " << volumeName << " FROM " << previousStepLimit << " mm TO "
369  << newStepLimit << " mm";
370  }
371  else {
372  MF_LOG_WARNING("LArG4DetectorService::setStepLimits")
373  << "New stepLimit matches previously"
374  << " set stepLimit from the GDML file for volume : " << volumeName
375  << " stepLimit : " << newStepLimit << " mm. Nothing will be changed.";
376  continue;
377  }
378  } //--check if new steplimit differs from a previously set value
379 
380  fStepLimitOverride->SetMaxAllowedStep(newStepLimit); // -- !
381  mf::LogInfo("LArG4DetectorService::setStepLimits")
382  << "fStepLimitOverride: " << newStepLimit / CLHEP::mm << " mm " << newStepLimit / CLHEP::cm
383  << " cm "
384  << "for volume: " << volumeName << "\n"
385  << "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
386  setVol->SetUserLimits(fStepLimitOverride);
387  } //--loop over input volumes
388 } //--end of setStepLimit()
389 
390 std::string larg4::LArG4DetectorService::instanceName(std::string const& volume_name) const
391 {
392  return myName() + volume_name;
393 }
394 
396 {
397  // Tell Art what we produce, and label the entries
398  for (auto const& [volume_name, sd_name] : detectors_) {
399  if (sd_name == "DRCalorimeter") {
400  auto const instance = instanceName(volume_name);
401  collector.produces<artg4tk::DRCalorimeterHitCollection>(instance);
402  collector.produces<artg4tk::ByParticle>(instance + "Edep");
403  collector.produces<artg4tk::ByParticle>(instance + "NCeren");
404  }
405  else if (sd_name == "Calorimeter") {
406  collector.produces<artg4tk::CalorimeterHitCollection>(instanceName(volume_name));
407  }
408  else if (sd_name == "PhotonDetector") {
409  collector.produces<artg4tk::PhotonHitCollection>(instanceName(volume_name));
410  }
411  else if (sd_name == "Tracker") {
412  collector.produces<artg4tk::TrackerHitCollection>(instanceName(volume_name));
413  }
414  else if (sd_name == "SimEnergyDeposit") {
415  collector.produces<sim::SimEnergyDepositCollection>(instanceName(volume_name));
416  }
417  else if (sd_name == "AuxDet") {
418  collector.produces<sim::AuxDetHitCollection>(instanceName(volume_name));
419  }
420  else if (sd_name == "HadInteraction") {
421  collector.produces<artg4tk::ArtG4tkVtx>(); // do NOT use product instance name (for now)
422  }
423  else if (sd_name == "HadIntAndEdepTrk") {
424  collector.produces<artg4tk::ArtG4tkVtx>();
425  collector.produces<artg4tk::TrackerHitCollection>();
426  }
427  }
428 }
429 
431 {
432  //
433  // NOTE(JVY): 1st hadronic interaction will be fetched as-is from HadInteractionSD
434  // a copy (via copy ctor) will be placed directly into art::Event
435  //
436  G4SDManager* sdman = G4SDManager::GetSDMpointer();
438  art::Event& e = detectorHolder->getCurrArtEvent();
439 
440  //add in PartliceListActionService ...
442 
443  for (auto const& [volume_name, sd_name] : detectors_) {
444  auto sd = sdman->FindSensitiveDetector(volume_name + "_" + sd_name);
445  if (sd_name == "HadInteraction") {
446  if (auto hisd = dynamic_cast<artg4tk::HadInteractionSD*>(sd)) {
447  if (auto const& inter = hisd->Get1stInteraction(); inter.GetNumOutcoming() > 0) {
448  e.put(make_product(inter));
449  }
450  hisd->clear();
451  }
452  }
453  else if (sd_name == "HadIntAndEdepTrk") {
454  if (auto trksd = dynamic_cast<artg4tk::HadIntAndEdepTrkSD*>(sd)) {
455  if (auto const& inter = trksd->Get1stInteraction(); inter.GetNumOutcoming() > 0) {
456  e.put(make_product(inter));
457  }
458  if (auto const& trkhits = trksd->GetEdepTrkHits(); !trkhits.empty()) {
459  e.put(make_product(trkhits));
460  }
461  trksd->clear();
462  }
463  }
464  else if (sd_name == "Tracker") {
465  auto trsd = dynamic_cast<artg4tk::TrackerSD*>(sd);
466  e.put(make_product(trsd->GetHits()), instanceName(volume_name));
467  }
468  else if (sd_name == "SimEnergyDeposit") {
469  auto sedsd = dynamic_cast<SimEnergyDepositSD*>(sd);
470  sim::SimEnergyDepositCollection hitCollection = sedsd->GetHits();
471  std::map<int, int> tmap = particleListAction->GetTargetIDMap();
473  for (auto& hit : hitCollection) {
474  hit.setTrackID(tmap[hit.TrackID()]);
475  }
476  }
477  e.put(make_product(hitCollection), instanceName(volume_name));
478  }
479  else if (sd_name == "AuxDet") {
480  auto auxsd = dynamic_cast<AuxDetSD*>(sd);
481  sim::AuxDetHitCollection hitCollection = auxsd->GetHits();
482  std::map<int, int> tmap = particleListAction->GetTargetIDMap();
483  if (updateAuxDetHits_) {
484  for (auto& hit : hitCollection) {
485  hit.SetTrackID(tmap[hit.GetTrackID()]);
486  }
487  }
488  e.put(make_product(auxsd->GetHits()), instanceName(volume_name));
489  }
490  else if (sd_name == "Calorimeter") {
491  auto calsd = dynamic_cast<artg4tk::CalorimeterSD*>(sd);
492  e.put(make_product(calsd->GetHits()), instanceName(volume_name));
493  }
494  else if (sd_name == "DRCalorimeter") {
495  auto drcalsd = dynamic_cast<artg4tk::DRCalorimeterSD*>(sd);
496  auto const identifier = instanceName(volume_name);
497  e.put(make_product(drcalsd->GetHits()), identifier);
498  e.put(make_product(drcalsd->GetEbyParticle()), identifier + "Edep");
499  e.put(make_product(drcalsd->GetNCerenbyParticle()), identifier + "NCeren");
500  }
501  else if (sd_name == "PhotonDetector") {
502  auto phsd = dynamic_cast<artg4tk::PhotonSD*>(sd);
503  e.put(make_product(phsd->GetHits()), instanceName(volume_name));
504  }
505  }
506 }
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
std::vector< G4LogicalVolume * > doBuildLVs() override
void doCallArtProduces(art::ProducesCollector &collector) override
const std::string instance
void doFillEventWithArtHits(G4HCofThisEvent *hc) override
LArG4DetectorService(fhicl::ParameterSet const &)
std::string instanceName(std::string const &) const
std::vector< std::pair< std::string, std::string > > detectors_
PutHandle< PROD > put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
Definition: Event.h:77
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:101
std::string const & myName() const
void produces(std::string const &instanceName={}, Persistable const persistable=Persistable::Yes)
Use Geant4&#39;s user "hooks" to maintain a list of particles generated by Geant4.
T get(std::string const &key) const
Definition: ParameterSet.h:314
const sim::SimEnergyDepositCollection & GetHits() const
volt_as<> volt
Type of potential stored in volts, in double precision.
std::vector< std::string > volumeNames_
CommandLineParser * parser(0)
std::vector< G4VPhysicalVolume * > doPlaceToPVs(std::vector< G4LogicalVolume * >) override
std::vector< float > stepLimits_
double value
Definition: spectrum.C:18
Detector simulation of raw signals on wires.
std::vector< AuxDetHit > AuxDetHitCollection
Definition: AuxDetHit.h:126
std::vector< SimEnergyDeposit > SimEnergyDepositCollection
decltype(auto) get(T &&obj)
ADL-aware version of std::to_string.
Definition: StdUtils.h:120
contains information for a single step in the detector simulation
#define MF_LOG_DEBUG(id)
#define MF_LOG_WARNING(category)
Float_t e
Definition: plot.C:35
const sim::AuxDetHitCollection & GetHits() const
Definition: AuxDetSD.h:33
std::map< std::string, G4double > overrideGDMLStepLimit_Map
std::unordered_map< std::string, float > setGDMLVolumes_
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33