Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-09 08:27:56

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 /// \file B02ImportanceDetectorConstruction.cc
0027 /// \brief Implementation of the B02ImportanceDetectorConstruction class
0028 
0029 #include "B02ImportanceDetectorConstruction.hh"
0030 
0031 #include "G4LogicalVolume.hh"
0032 #include "G4Material.hh"
0033 #include "G4PVPlacement.hh"
0034 #include "G4PhysicalConstants.hh"
0035 #include "G4SystemOfUnits.hh"
0036 #include "G4ThreeVector.hh"
0037 #include "G4Tubs.hh"
0038 #include "globals.hh"
0039 
0040 #include <sstream>
0041 
0042 // For Primitive Scorers
0043 #include "G4MultiFunctionalDetector.hh"
0044 #include "G4PSNofCollision.hh"
0045 #include "G4PSPopulation.hh"
0046 #include "G4PSTrackCounter.hh"
0047 #include "G4PSTrackLength.hh"
0048 #include "G4SDManager.hh"
0049 #include "G4SDParticleFilter.hh"
0050 
0051 // for importance biasing
0052 #include "G4IStore.hh"
0053 
0054 // for weight window technique
0055 #include "G4WeightWindowStore.hh"
0056 
0057 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0058 
0059 B02ImportanceDetectorConstruction::B02ImportanceDetectorConstruction(G4String worldName)
0060   : G4VUserParallelWorld(worldName), fLogicalVolumeVector()
0061 {
0062   //  Construct();
0063 }
0064 
0065 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0066 
0067 B02ImportanceDetectorConstruction::~B02ImportanceDetectorConstruction()
0068 {
0069   fLogicalVolumeVector.clear();
0070 }
0071 
0072 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0073 
0074 void B02ImportanceDetectorConstruction::Construct()
0075 {
0076   G4cout << " constructing parallel world " << G4endl;
0077 
0078   G4Material* dummyMat = 0;
0079 
0080   // GetWorld methods create a clone of the mass world to the parallel world (!)
0081   //  via the transportation manager
0082   fGhostWorld = GetWorld();
0083   G4cout << " B02ImportanceDetectorConstruction:: ghostWorldName = " << fGhostWorld->GetName()
0084          << G4endl;
0085   G4LogicalVolume* worldLogical = fGhostWorld->GetLogicalVolume();
0086   fLogicalVolumeVector.push_back(worldLogical);
0087 
0088   //  fPVolumeStore.AddPVolume(G4GeometryCell(*pWorldVolume, 0));
0089   fPVolumeStore.AddPVolume(G4GeometryCell(*fGhostWorld, 0));
0090 
0091   // creating 18 slobs of 10 cm thicknes
0092 
0093   G4double innerRadiusShield = 0 * cm;
0094   G4double outerRadiusShield = 100 * cm;
0095   G4double heightShield = 5 * cm;
0096   G4double startAngleShield = 0 * deg;
0097   G4double spanningAngleShield = 360 * deg;
0098 
0099   G4Tubs* aShield = new G4Tubs("aShield", innerRadiusShield, outerRadiusShield, heightShield,
0100                                startAngleShield, spanningAngleShield);
0101 
0102   // logical parallel cells
0103 
0104   G4LogicalVolume* aShield_log_imp = new G4LogicalVolume(aShield, dummyMat, "aShield_log_imp");
0105   fLogicalVolumeVector.push_back(aShield_log_imp);
0106 
0107   // physical parallel cells
0108   G4String name = "none";
0109   G4int i = 1;
0110   G4double startz = -85 * cm;
0111   //  for (i=1; i<=18; ++i) {
0112   for (i = 1; i <= 18; i++) {
0113     name = GetCellName(i);
0114 
0115     G4double pos_x = 0 * cm;
0116     G4double pos_y = 0 * cm;
0117     G4double pos_z = startz + (i - 1) * (2 * heightShield);
0118     G4VPhysicalVolume* pvol = new G4PVPlacement(0, G4ThreeVector(pos_x, pos_y, pos_z),
0119                                                 aShield_log_imp, name, worldLogical, false, i);
0120     //                        0);
0121     G4GeometryCell cell(*pvol, i);
0122     //    G4GeometryCell cell(*pvol, 0);
0123     fPVolumeStore.AddPVolume(cell);
0124   }
0125 
0126   // filling the rest of the world volumr behind the concrete with
0127   // another slob which should get the same importance value as the
0128   // last slob
0129   innerRadiusShield = 0 * cm;
0130   //  outerRadiusShield = 110*cm; exceeds world volume!!!!
0131   outerRadiusShield = 100 * cm;
0132   //  heightShield       = 10*cm;
0133   heightShield = 5 * cm;
0134   startAngleShield = 0 * deg;
0135   spanningAngleShield = 360 * deg;
0136 
0137   G4Tubs* aRest = new G4Tubs("Rest", innerRadiusShield, outerRadiusShield, heightShield,
0138                              startAngleShield, spanningAngleShield);
0139 
0140   G4LogicalVolume* aRest_log = new G4LogicalVolume(aRest, dummyMat, "aRest_log");
0141 
0142   fLogicalVolumeVector.push_back(aRest_log);
0143 
0144   name = GetCellName(19);
0145 
0146   G4double pos_x = 0 * cm;
0147   G4double pos_y = 0 * cm;
0148   //  G4double pos_z = 100*cm;
0149   G4double pos_z = 95 * cm;
0150   G4VPhysicalVolume* pvol = new G4PVPlacement(0, G4ThreeVector(pos_x, pos_y, pos_z), aRest_log,
0151                                               name, worldLogical, false, 19);
0152   //                      0);
0153   G4GeometryCell cell(*pvol, 19);
0154   //  G4GeometryCell cell(*pvol, 0);
0155   fPVolumeStore.AddPVolume(cell);
0156 
0157   SetSensitive();
0158 }
0159 
0160 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0161 
0162 const G4VPhysicalVolume&
0163 B02ImportanceDetectorConstruction::GetPhysicalVolumeByName(const G4String& name) const
0164 {
0165   return *fPVolumeStore.GetPVolume(name);
0166 }
0167 
0168 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0169 
0170 G4String B02ImportanceDetectorConstruction::ListPhysNamesAsG4String()
0171 {
0172   G4String names(fPVolumeStore.GetPNames());
0173   return names;
0174 }
0175 
0176 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0177 
0178 G4String B02ImportanceDetectorConstruction::GetCellName(G4int i)
0179 {
0180   std::ostringstream os;
0181   os << "cell_";
0182   if (i < 10) {
0183     os << "0";
0184   }
0185   os << i;
0186   G4String name = os.str();
0187   return name;
0188 }
0189 
0190 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0191 
0192 G4GeometryCell B02ImportanceDetectorConstruction::GetGeometryCell(G4int i)
0193 {
0194   G4String name(GetCellName(i));
0195   const G4VPhysicalVolume* p = 0;
0196   p = fPVolumeStore.GetPVolume(name);
0197   if (p) {
0198     return G4GeometryCell(*p, 0);
0199   }
0200   else {
0201     G4cout << "B02ImportanceDetectorConstruction::GetGeometryCell: " << G4endl
0202            << " couldn't get G4GeometryCell" << G4endl;
0203     return G4GeometryCell(*fGhostWorld, -2);
0204   }
0205 }
0206 
0207 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0208 
0209 G4VPhysicalVolume& B02ImportanceDetectorConstruction::GetWorldVolumeAddress() const
0210 {
0211   return *fGhostWorld;
0212 }
0213 
0214 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0215 
0216 G4VPhysicalVolume* B02ImportanceDetectorConstruction::GetWorldVolume()
0217 {
0218   return fGhostWorld;
0219 }
0220 
0221 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0222 
0223 void B02ImportanceDetectorConstruction::SetSensitive()
0224 {
0225   //  -------------------------------------------------
0226   //   The collection names of defined Primitives are
0227   //   0       ConcreteSD/Collisions
0228   //   1       ConcreteSD/CollWeight
0229   //   2       ConcreteSD/Population
0230   //   3       ConcreteSD/TrackEnter
0231   //   4       ConcreteSD/SL
0232   //   5       ConcreteSD/SLW
0233   //   6       ConcreteSD/SLWE
0234   //   7       ConcreteSD/SLW_V
0235   //   8       ConcreteSD/SLWE_V
0236   //  -------------------------------------------------
0237 
0238   // moved to ConstructSD() for MT compliance
0239 }
0240 
0241 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0242 void B02ImportanceDetectorConstruction::ConstructSD()
0243 {
0244   G4SDManager* SDman = G4SDManager::GetSDMpointer();
0245   //
0246   // Sensitive Detector Name
0247   G4String concreteSDname = "ConcreteSD";
0248 
0249   //------------------------
0250   // MultiFunctionalDetector
0251   //------------------------
0252   //
0253   // Define MultiFunctionalDetector with name.
0254   G4MultiFunctionalDetector* MFDet = new G4MultiFunctionalDetector(concreteSDname);
0255   SDman->AddNewDetector(MFDet);  // Register SD to SDManager
0256 
0257   G4String fltName, particleName;
0258   G4SDParticleFilter* neutronFilter =
0259     new G4SDParticleFilter(fltName = "neutronFilter", particleName = "neutron");
0260 
0261   MFDet->SetFilter(neutronFilter);
0262 
0263   for (std::vector<G4LogicalVolume*>::iterator it = fLogicalVolumeVector.begin();
0264        it != fLogicalVolumeVector.end(); it++)
0265   {
0266     //      (*it)->SetSensitiveDetector(MFDet);
0267     SetSensitiveDetector((*it)->GetName(), MFDet);
0268   }
0269 
0270   G4String psName;
0271   G4PSNofCollision* scorer0 = new G4PSNofCollision(psName = "Collisions");
0272   MFDet->RegisterPrimitive(scorer0);
0273 
0274   G4PSNofCollision* scorer1 = new G4PSNofCollision(psName = "CollWeight");
0275   scorer1->Weighted(true);
0276   MFDet->RegisterPrimitive(scorer1);
0277 
0278   G4PSPopulation* scorer2 = new G4PSPopulation(psName = "Population");
0279   MFDet->RegisterPrimitive(scorer2);
0280 
0281   G4PSTrackCounter* scorer3 = new G4PSTrackCounter(psName = "TrackEnter", fCurrent_In);
0282   MFDet->RegisterPrimitive(scorer3);
0283 
0284   G4PSTrackLength* scorer4 = new G4PSTrackLength(psName = "SL");
0285   MFDet->RegisterPrimitive(scorer4);
0286 
0287   G4PSTrackLength* scorer5 = new G4PSTrackLength(psName = "SLW");
0288   scorer5->Weighted(true);
0289   MFDet->RegisterPrimitive(scorer5);
0290 
0291   G4PSTrackLength* scorer6 = new G4PSTrackLength(psName = "SLWE");
0292   scorer6->Weighted(true);
0293   scorer6->MultiplyKineticEnergy(true);
0294   MFDet->RegisterPrimitive(scorer6);
0295 
0296   G4PSTrackLength* scorer7 = new G4PSTrackLength(psName = "SLW_V");
0297   scorer7->Weighted(true);
0298   scorer7->DivideByVelocity(true);
0299   MFDet->RegisterPrimitive(scorer7);
0300 
0301   G4PSTrackLength* scorer8 = new G4PSTrackLength(psName = "SLWE_V");
0302   scorer8->Weighted(true);
0303   scorer8->MultiplyKineticEnergy(true);
0304   scorer8->DivideByVelocity(true);
0305   MFDet->RegisterPrimitive(scorer8);
0306 }
0307 
0308 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0309 G4VIStore* B02ImportanceDetectorConstruction::CreateImportanceStore()
0310 {
0311   G4cout << " B02ImportanceDetectorConstruction:: Creating Importance Store " << G4endl;
0312   if (!fPVolumeStore.Size()) {
0313     G4Exception("B02ImportanceDetectorConstruction::CreateImportanceStore", "exampleB02_0001",
0314                 RunMustBeAborted, "no physical volumes created yet!");
0315   }
0316 
0317   // creating and filling the importance store
0318 
0319   //  G4IStore *istore = new G4IStore(*fWorldVolume);
0320 
0321   G4IStore* istore = G4IStore::GetInstance(GetName());
0322 
0323   G4GeometryCell gWorldVolumeCell(GetWorldVolumeAddress(), 0);
0324 
0325   G4double imp = 1;
0326 
0327   istore->AddImportanceGeometryCell(1, gWorldVolumeCell);
0328 
0329   // set importance values and create scorers
0330   G4int cell(1);
0331   for (cell = 1; cell <= 18; cell++) {
0332     G4GeometryCell gCell = GetGeometryCell(cell);
0333     G4cout << " adding cell: " << cell << " replica: " << gCell.GetReplicaNumber()
0334            << " name: " << gCell.GetPhysicalVolume().GetName() << G4endl;
0335     imp = std::pow(2.0, cell - 1);
0336 
0337     G4cout << "Going to assign importance: " << imp
0338            << ", to volume: " << gCell.GetPhysicalVolume().GetName() << G4endl;
0339     // x    aIstore.AddImportanceGeometryCell(imp, gCell);
0340     istore->AddImportanceGeometryCell(imp, gCell.GetPhysicalVolume(), cell);
0341   }
0342 
0343   // creating the geometry cell and add both to the store
0344   //  G4GeometryCell gCell = GetGeometryCell(18);
0345 
0346   // create importance geometry cell pair for the "rest"cell
0347   // with the same importance as the last concrete cell
0348   G4GeometryCell gCell = GetGeometryCell(19);
0349   //  G4double imp = std::pow(2.0,18);
0350   imp = std::pow(2.0, 17);
0351   istore->AddImportanceGeometryCell(imp, gCell.GetPhysicalVolume(), 19);
0352 
0353   return istore;
0354 }
0355 
0356 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0357 
0358 G4VWeightWindowStore* B02ImportanceDetectorConstruction::CreateWeightWindowStore()
0359 {
0360   G4cout << " B02ImportanceDetectorConstruction:: Creating Importance Store " << G4endl;
0361   if (!fPVolumeStore.Size()) {
0362     G4Exception("B02ImportanceDetectorConstruction::CreateWeightWindowStore", "exampleB02_0002",
0363                 RunMustBeAborted, "no physical volumes created yet!");
0364   }
0365 
0366   // creating and filling the importance store
0367 
0368   //  G4IStore *istore = new G4IStore(*fWorldVolume);
0369 
0370   G4WeightWindowStore* wwstore = G4WeightWindowStore::GetInstance(GetName());
0371 
0372   // create one energy region covering the energies of the problem
0373   //
0374   std::set<G4double, std::less<G4double>> enBounds;
0375   enBounds.insert(1 * GeV);
0376   wwstore->SetGeneralUpperEnergyBounds(enBounds);
0377 
0378   G4int n = 0;
0379   G4double lowerWeight = 1;
0380   std::vector<G4double> lowerWeights;
0381 
0382   lowerWeights.push_back(1);
0383   G4GeometryCell gWorldCell(GetWorldVolumeAddress(), 0);
0384   wwstore->AddLowerWeights(gWorldCell, lowerWeights);
0385 
0386   G4int cell(1);
0387   for (cell = 1; cell <= 18; cell++) {
0388     G4GeometryCell gCell = GetGeometryCell(cell);
0389     G4cout << " adding cell: " << cell << " replica: " << gCell.GetReplicaNumber()
0390            << " name: " << gCell.GetPhysicalVolume().GetName() << G4endl;
0391 
0392     lowerWeight = 1. / std::pow(2., n++);
0393     G4cout << "Going to assign lower weight: " << lowerWeight
0394            << ", to volume: " << gCell.GetPhysicalVolume().GetName() << G4endl;
0395     lowerWeights.clear();
0396     lowerWeights.push_back(lowerWeight);
0397     wwstore->AddLowerWeights(gCell, lowerWeights);
0398   }
0399 
0400   // the remaining part pf the geometry (rest) gets the same
0401   // lower weight bound  as the last conrete cell
0402   //
0403 
0404   // create importance geometry cell pair for the "rest"cell
0405   // with the same importance as the last concrete cell
0406   G4GeometryCell gCell = GetGeometryCell(19);
0407   wwstore->AddLowerWeights(gCell, lowerWeights);
0408 
0409   return wwstore;
0410 }