diff --git a/libs/include/PatternTypes.hpp b/libs/include/PatternTypes.hpp index 3be6db7..d751ef5 100644 --- a/libs/include/PatternTypes.hpp +++ b/libs/include/PatternTypes.hpp @@ -13,6 +13,8 @@ class PatternTypes void buildTypes(); bool hasType(const G4String& name); Pattern& operator[](const G4String& name){return m_Pattern[name];} + std::map::iterator begin(){return m_Pattern.begin();} + std::map::iterator end(){return m_Pattern.end();} private: void verifyParameters(); nlohmann::json m_Json{}; @@ -20,3 +22,5 @@ class PatternTypes G4String m_Type{""}; std::map m_Pattern; }; + +using PatternTypesIterator=std::map::iterator; diff --git a/libs/include/SDHCALDetectorConstruction.hpp b/libs/include/SDHCALDetectorConstruction.hpp index 12b573c..afddc55 100644 --- a/libs/include/SDHCALDetectorConstruction.hpp +++ b/libs/include/SDHCALDetectorConstruction.hpp @@ -1,7 +1,6 @@ #pragma once #include "G4VUserDetectorConstruction.hh" -#include "CLHEP/Units/SystemOfUnits.h" #include "json.hpp" @@ -17,23 +16,21 @@ public : G4double getCaloSizeX(){return m_CaloSizeX;} G4double getCaloSizeY(){return m_CaloSizeY;} G4double getCaloSizeZ(){return m_CaloSizeZ;} - + private: G4String m_TypesRPC{""}; G4String m_TypesAbsorber{""}; std::vector m_GasGap; - std::vector m_LogicRPC; G4bool oldConfig = false ; nlohmann::json m_Json{}; G4int m_NbrLayers{0}; G4int m_NbrCellX{0}; G4int m_NbrCellY{0}; - G4double m_CellSizeX{10.408*CLHEP::mm}; - G4double m_CellSizeY{10.408*CLHEP::mm}; + G4double m_CellSizeX{0.}; + G4double m_CellSizeY{0.}; G4double m_CaloSizeX{0.}; G4double m_CaloSizeY{0.}; G4double m_CaloSizeZ{0.}; PatternTypes m_RPCTypes{PatternTypes("RPC")}; PatternTypes m_AbsorberTypes{PatternTypes("Absorber")}; }; - diff --git a/libs/src/PatternTypes.cpp b/libs/src/PatternTypes.cpp index d932c38..3c80ef0 100644 --- a/libs/src/PatternTypes.cpp +++ b/libs/src/PatternTypes.cpp @@ -72,7 +72,6 @@ void PatternTypes::buildTypes() { m_Pattern[it->at("Name")].addLayer(itt->at("Name").get(),itt->at("Width").get(),itt->at("Material").get()); } - m_Pattern[it->at("Name")].print(); } } else diff --git a/libs/src/SDHCALDetectorConstruction.cpp b/libs/src/SDHCALDetectorConstruction.cpp index 433cc23..c7f41f5 100644 --- a/libs/src/SDHCALDetectorConstruction.cpp +++ b/libs/src/SDHCALDetectorConstruction.cpp @@ -16,12 +16,12 @@ void SDHCALDetectorConstruction::ConstructSDandField() { for( G4int i = 0 ; i < m_NbrLayers ; ++i ) { - std::string sensName="RPC"+std::to_string(i); - SDHCALRPCSensitiveDetector* sensitiveDetector = new SDHCALRPCSensitiveDetector(sensName,i); - sensitiveDetector->setSizes(m_CaloSizeX,m_CaloSizeY,m_CaloSizeZ); - sensitiveDetector->setCellXYSize(m_CellSizeX,m_CellSizeY); - G4SDManager::GetSDMpointer()->AddNewDetector(sensitiveDetector); - m_GasGap[i]->SetSensitiveDetector(sensitiveDetector); + std::string sensName="RPC"+std::to_string(i); + SDHCALRPCSensitiveDetector* sensitiveDetector = new SDHCALRPCSensitiveDetector(sensName,i); + sensitiveDetector->setSizes(m_CaloSizeX,m_CaloSizeY,m_CaloSizeZ); + sensitiveDetector->setCellXYSize(m_CellSizeX,m_CellSizeY); + G4SDManager::GetSDMpointer()->AddNewDetector(sensitiveDetector); + m_GasGap[i]->SetSensitiveDetector(sensitiveDetector); } } @@ -31,6 +31,15 @@ SDHCALDetectorConstruction::SDHCALDetectorConstruction(const nlohmann::json& jso m_RPCTypes.setJsonFile(m_Json); m_RPCTypes.buildTypes(); m_AbsorberTypes.buildTypes(); + for(PatternTypesIterator it=m_RPCTypes.begin();it!=m_RPCTypes.end();++it) + { + if(!it->second.hasLayer("GasGap")) + { + G4cerr<<"RPCType "<second.getName()<<" doesn't have a GasGap layer ! !"<(); } m_GasGap.reserve(m_NbrLayers); - m_LogicRPC.reserve(m_NbrLayers); for(G4int i=0;i!=m_NbrLayers;++i) { m_GasGap[i]=nullptr; - m_LogicRPC[i]=nullptr; } } @@ -89,16 +96,11 @@ G4VPhysicalVolume* SDHCALDetectorConstruction::Construct() buildSDHCALMaterials(); G4NistManager* man = G4NistManager::Instance(); - - G4Material* absorberMaterial = G4Material::GetMaterial("SDHCAL_Steel304L" , true); - //to reproduce old results - if(oldConfig) absorberMaterial = G4Material::GetMaterial("SDHCAL_Steel304L_Old" , true); - // World G4Box* solidWorld = new G4Box("World", worldSize/2 , worldSize/2 , worldSize/2); G4LogicalVolume* logicWorld = new G4LogicalVolume(solidWorld ,G4Material::GetMaterial("G4_Galactic",true), "World"); G4VPhysicalVolume* physiWorld=new G4PVPlacement(nullptr,G4ThreeVector(),logicWorld,"World",nullptr,false,0,true); - + //Calculate the size of the calorimeter for(G4int i = 0;i < m_NbrLayers ;++i) { @@ -110,26 +112,45 @@ G4VPhysicalVolume* SDHCALDetectorConstruction::Construct() //Build Calorimeter Volume G4Box* solidCalorimeter = new G4Box("Calorimeter",m_CaloSizeX/2,m_CaloSizeY/2,m_CaloSizeZ/2); G4LogicalVolume* logicCalorimeter = new G4LogicalVolume(solidCalorimeter,G4Material::GetMaterial("G4_AIR",true),"Calorimeter"); - //Start at -m_CaloSizeZ/2 as the origin is at the center of the calorimeter box - - + new G4PVPlacement(nullptr,G4ThreeVector(0,0,0.5*m_CaloSizeZ),logicCalorimeter,"Calorimeter",logicWorld,false,0,true); - + //Start at -m_CaloSizeZ/2 as the origin is at the center of the calorimeter box + G4double currentPos = -m_CaloSizeZ/2; for( G4int i = 0 ; i < m_NbrLayers ; ++i) { + //////////////////////////////////// + /////////////////////////////////// + //Build Absorber + //////////////////////////////////// + /////////////////////////////////// + for(G4int j=0;j!=m_AbsorberTypes[m_TypesAbsorber].getNbrLayers();++j) + { + auto material = man->FindOrBuildMaterial(m_AbsorberTypes[m_TypesAbsorber].getLayerMaterial(j)); + if(!material) + { + G4cerr << "Error : material " << m_AbsorberTypes[m_TypesAbsorber].getLayerMaterial(j) << " not known" << G4endl; + std::exit(-1); + } + //create logic layer volume (indefined placement) + auto solid = new G4Box(m_AbsorberTypes[m_TypesAbsorber].getLayerName(j) , m_CaloSizeX/2 , m_CaloSizeY/2 , m_AbsorberTypes[m_TypesAbsorber].getLayerWidth(j)/2); + auto logic = new G4LogicalVolume(solid , material ,m_AbsorberTypes[m_TypesAbsorber].getLayerName(j)); + currentPos += m_AbsorberTypes[m_TypesAbsorber].getLayerWidth(j)/2; //we are now at center of the current layer (where it has to be placed) + new G4PVPlacement(nullptr , G4ThreeVector(0,0,currentPos) , logic , m_AbsorberTypes[m_TypesAbsorber].getLayerName(j),logicCalorimeter,false,0,true); + currentPos += m_AbsorberTypes[m_TypesAbsorber].getLayerWidth(j)/2; //we are now at the back of the current layer + } + //////////////////////////////////// + /////////////////////////////////// + //Build RPC + //////////////////////////////////// + /////////////////////////////////// G4String m_Name="Cassette"+std::to_string(i); - //compute total RPC cassette width G4double cassetteThickness = m_RPCTypes[m_TypesRPC].getWidth(); - - //create logic RPC volume (indefined placement) G4Box* solidCassette = new G4Box(m_Name , m_CaloSizeX/2, m_CaloSizeY/2, cassetteThickness/2); - m_LogicRPC[i] = new G4LogicalVolume(solidCassette ,G4Material::GetMaterial("G4_Galactic",true),m_Name); - - //construct all the layers + G4LogicalVolume* logicRPC = new G4LogicalVolume(solidCassette ,G4Material::GetMaterial("G4_Galactic",true),m_Name); + //construct all the layers of the cassette G4double zPos = -cassetteThickness/2; //we start at front of the cassette for(G4int j=0;j!=m_RPCTypes[m_TypesRPC].getNbrLayers();++j) { - std::cout<FindOrBuildMaterial(m_RPCTypes[m_TypesRPC].getLayerMaterial(j)); if(!material) { @@ -143,7 +164,7 @@ G4VPhysicalVolume* SDHCALDetectorConstruction::Construct() zPos += m_RPCTypes[m_TypesRPC].getLayerWidth(j)/2; //we are now at center of the current layer (where it has to be placed) //place the layer at zPos - new G4PVPlacement(nullptr , G4ThreeVector(0,0,zPos) , logic , m_RPCTypes[m_TypesRPC].getLayerName(j)+std::to_string(i) , m_LogicRPC[i],false,0,true); //m_LogicRPC is the mother volume + new G4PVPlacement(nullptr , G4ThreeVector(0,0,zPos) , logic , m_RPCTypes[m_TypesRPC].getLayerName(j)+std::to_string(i) , logicRPC,false,0,true); //m_LogicRPC is the mother volume zPos += m_RPCTypes[m_TypesRPC].getLayerWidth(j)/2; //we are now at the back of the current layer @@ -158,43 +179,16 @@ G4VPhysicalVolume* SDHCALDetectorConstruction::Construct() m_GasGap[i] = logic; } } - - if(!m_GasGap[i]) //if we don't have the gas gap we have a problem - { - G4cerr << "Error : no gas gap in the RPC" << G4endl; - std::exit(-1); - } + //////////////////////////////////// + /////////////////////////////////// + //Place the RPC + //////////////////////////////////// + /////////////////////////////////// + currentPos += m_RPCTypes[m_TypesRPC].getWidth()/2; + new G4PVPlacement(nullptr,G4ThreeVector(0,0,currentPos), logicRPC ,"Cassette"+std::to_string(i) ,logicCalorimeter , false , 0 , true); + currentPos += m_RPCTypes[m_TypesRPC].getWidth()/2; } - - //G4double RPCSizeZ = rpcVec.at(0).getSizeZ(); - G4double absorberStructureSizeZ = 15*CLHEP::mm; - - G4double airGapSizeZ = 1*CLHEP::mm; - // to reproduce old results - if(oldConfig) airGapSizeZ = 0*CLHEP::mm; - - - - - - - G4double currentPos = -m_CaloSizeZ/2; - for ( G4int i = 0 ; i < m_NbrLayers ; ++i ) - { - currentPos += absorberStructureSizeZ/2; - G4Box* solidAbsorberStructure = new G4Box("AbsorberStructure",m_CaloSizeX/2,m_CaloSizeY/2,absorberStructureSizeZ/2); - G4LogicalVolume* logicAbsorberStructure = new G4LogicalVolume(solidAbsorberStructure,absorberMaterial,"AbsorberStructure"); - new G4PVPlacement(nullptr,G4ThreeVector(0,0,currentPos),logicAbsorberStructure,"AbsorberStructure",logicCalorimeter,false,0,true); - - currentPos += absorberStructureSizeZ/2 + airGapSizeZ + m_RPCTypes[m_TypesRPC].getWidth()/2; - new G4PVPlacement(nullptr,G4ThreeVector(0,0,currentPos), m_LogicRPC[i] ,"Cassette"+std::to_string(i) ,logicCalorimeter , false , 0 , true); - - currentPos += m_RPCTypes[m_TypesRPC].getWidth()/2 + airGapSizeZ; - } - - new G4PVPlacement(nullptr,G4ThreeVector(0,0,0.5*m_CaloSizeZ),logicCalorimeter,"Calorimeter",logicWorld,false,0,true); - //for stepping action G4Region* regionCalor = G4RegionStore::GetInstance()->FindOrCreateRegion("RegionCalorimeter"); regionCalor->AddRootLogicalVolume(logicCalorimeter);