Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-02 07:35:37

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 // CaTS (Calorimetry and Tracking Simulation)
0027 //
0028 // Authors: Hans Wenzel and Soon Yung Jun
0029 //          (Fermi National Accelerator Laboratory)
0030 //
0031 // History: October 18th, 2021 : first implementation
0032 //
0033 // ********************************************************************
0034 //
0035 /// \file DetectorConstruction.cc
0036 /// \brief Implementation of the CaTS::DetectorConstruction class
0037 
0038 // Geant4 headers
0039 #include "G4RunManager.hh"
0040 #include "G4PhysicalVolumeStore.hh"
0041 #include "G4LogicalVolumeStore.hh"
0042 #include "G4VisAttributes.hh"
0043 #include "G4UserLimits.hh"
0044 #include "G4ios.hh"
0045 #include "G4GDMLParser.hh"
0046 #include "G4SDManager.hh"
0047 // project headers
0048 #include "ConfigurationManager.hh"
0049 #include "DetectorConstruction.hh"
0050 #include "ColorReader.hh"
0051 // c++ headers
0052 #include <iostream>
0053 
0054 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0055 DetectorConstruction::DetectorConstruction(G4String fname)
0056   : G4VUserDetectorConstruction()
0057   , gdmlFile(fname)
0058 {}
0059 
0060 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0061 G4VPhysicalVolume* DetectorConstruction::Construct()
0062 {
0063   // Import the application geometry from a GDML file
0064   ReadGDML();
0065 
0066   const G4GDMLAuxMapType* auxmap = parser->GetAuxMap();
0067   verbose = ConfigurationManager::getInstance()->isEnable_verbose();
0068   if(verbose)
0069   {
0070     G4cout << "Found " << auxmap->size()
0071        << " volume(s) with auxiliary information." << G4endl;
0072   }
0073   for(G4GDMLAuxMapType::const_iterator iter = auxmap->begin();
0074       iter != auxmap->end(); iter++)
0075   {
0076     if(verbose)
0077     {
0078       G4cout << "Volume " << ((*iter).first)->GetName()
0079              << " has the following list of auxiliary information: " << G4endl;
0080     }
0081     for(G4GDMLAuxListType::const_iterator vit = (*iter).second.begin();
0082         vit != (*iter).second.end(); vit++)
0083     {
0084       if(verbose)
0085       {
0086         G4cout << "Type: " << (*vit).type << " Value: " << (*vit).value
0087            << G4endl;
0088       }
0089       if((*vit).type == "StepLimit")
0090       {
0091         G4UserLimits* fStepLimit = new G4UserLimits(atof((*vit).value));
0092         ((*iter).first)->SetUserLimits(fStepLimit);
0093       }
0094     }
0095   }
0096   G4VPhysicalVolume* worldPhysVol = parser->GetWorldVolume();
0097   if(ConfigurationManager::getInstance()->isDumpgdml())
0098   {
0099     std::ifstream ifile;
0100     G4String fileName = ConfigurationManager::getInstance()->getGDMLFileName();
0101     ifile.open(fileName);
0102     if(ifile)
0103     {
0104       G4cout << "**************************************************" << G4endl;
0105       G4cout << fileName << " already exists!!!" << G4endl;
0106       G4cout << "No new gdml dump created!!!" << G4endl;
0107       G4cout << "**************************************************" << G4endl;
0108     }
0109     else
0110     {
0111       G4cout << "Writing: " << fileName << G4endl;
0112       parser->Write(fileName, worldPhysVol);
0113     }
0114   }
0115   return worldPhysVol;
0116 }
0117 
0118 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0119 void DetectorConstruction::ConstructSDandField()
0120 {
0121   const G4GDMLAuxMapType* auxmap = parser->GetAuxMap();
0122   if(verbose)
0123   {
0124     G4cout << "Found " << auxmap->size()
0125            << " volume(s) with auxiliary information." << G4endl;
0126   }
0127 
0128   // Add a sensitive detector into the SD manager
0129   for(G4GDMLAuxMapType::const_iterator iter = auxmap->begin();
0130       iter != auxmap->end(); iter++)
0131   {
0132     G4LogicalVolume* volume = (*iter).first;
0133     G4String volName = volume->GetName();
0134 
0135     if(verbose)
0136     {
0137       G4cout << "Volume " << volName
0138              << " has the following list of auxiliary information: " << G4endl;
0139     }
0140     for(G4GDMLAuxListType::const_iterator vit = (*iter).second.begin();
0141         vit != (*iter).second.end(); vit++)
0142     {
0143       G4String auxType = (*vit).type;
0144       G4String auxValue = (*vit).value;
0145 
0146       if(verbose)
0147       {
0148         G4cout << "Aux Type: " << auxType << " Value: " << auxValue << G4endl;
0149       }
0150       if(auxType == "SensDet")
0151       {
0152         if(verbose)
0153         {
0154           G4cout << "Found sensitive Detector: " << auxValue << G4endl;
0155           G4cout << "Attaching it to Volume:  " << volName << G4endl;
0156         }
0157 
0158         const auto& sdMap = GetSDMap();
0159 
0160         if (auto it = sdMap.find(auxValue); it != sdMap.end())
0161         {
0162       // construct SD with given name
0163           auto sd = it->second(volume->GetName() + "_" + auxValue);
0164           G4SDManager::GetSDMpointer()->AddNewDetector(sd.get());
0165           volume->SetSensitiveDetector(sd.release());
0166         }
0167         else
0168         {
0169           G4cerr << "Unknown sensitive detector type: " << auxValue << G4endl;
0170         }
0171       }
0172       else if(auxType == "Solid" && auxValue == "True")
0173       {
0174         G4VisAttributes* visibility = new G4VisAttributes();
0175         visibility->SetForceSolid(true);
0176         G4VisAttributes* visatt = new G4VisAttributes(
0177           volume->GetVisAttributes()->GetColour());
0178         visatt->SetVisibility(true);
0179         visatt->SetForceSolid(true);
0180         visatt->SetForceAuxEdgeVisible(true);
0181         volume->SetVisAttributes(visatt);
0182       }
0183     }
0184   }
0185 }
0186 
0187 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0188 void DetectorConstruction::ReadGDML()
0189 {
0190   fReader = new ColorReader;
0191   parser  = new G4GDMLParser(fReader);
0192   parser->Read(gdmlFile, false);
0193 
0194   G4VPhysicalVolume* World = parser->GetWorldVolume();
0195   //----- GDML parser makes world invisible, this is a hack to make it
0196   // visible again...
0197   G4LogicalVolume* pWorldLogical = World->GetLogicalVolume();
0198   pWorldLogical->SetVisAttributes(0);
0199   G4cout << World->GetTranslation() << G4endl << G4endl;
0200 
0201   if(verbose)
0202   {
0203     G4cout << "Found World:  " << World->GetName() << G4endl;
0204     G4cout << "World LV:  " << World->GetLogicalVolume()->GetName() << G4endl;
0205     G4cout << "Found " << G4LogicalVolumeStore::GetInstance()->size()
0206        << " logical volumes." << G4endl;
0207     G4cout << "Found " << G4PhysicalVolumeStore::GetInstance()->size()
0208        << " physical volumes." << G4endl;
0209   }
0210 }
0211 
0212 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0213 void DetectorConstruction::UpdateGeometry()
0214 {
0215   G4RunManager::GetRunManager()->DefineWorldVolume(Construct());
0216 }