// %%%%%%%%%% // G4 headers // %%%%%%%%%% #include "G4Box.hh" #include "G4GeometryManager.hh" #include "G4LogicalVolumeStore.hh" #include "G4LogicalVolume.hh" #include "G4PhysicalVolumeStore.hh" #include "G4ProductionCuts.hh" #include "G4PVPlacement.hh" #include "G4RunManager.hh" #include "G4SolidStore.hh" #include "G4VisAttributes.hh" #include "G4SDManager.hh" #include "G4OpBoundaryProcess.hh" // %%%%%%%%%%%%% // gemc headers // %%%%%%%%%%%%% #include "MDetectorConstruction.h" #include "MDetectorMessenger.h" MDetectorConstruction::MDetectorConstruction(gemc_opts Opts) { gemcOpt = Opts; // mdetectorMessenger = new MDetectorMessenger(this); } MDetectorConstruction::~MDetectorConstruction() { ; } G4VPhysicalVolume* MDetectorConstruction::Construct() { string hd_msg = gemcOpt.args["LOG_MSG"].args + " Construction: >> "; double VERB = gemcOpt.args["G4P_VERBOSITY"].arg ; string catch_v = gemcOpt.args["CATCH"].args; string hall_mat = gemcOpt.args["HALL_MATERIAL"].args; string hall_field = gemcOpt.args["HALL_FIELD"].args; // Clean old geometry, if any G4GeometryManager::GetInstance()->OpenGeometry(); G4PhysicalVolumeStore::GetInstance()->Clean(); G4LogicalVolumeStore::GetInstance()->Clean(); G4SolidStore::GetInstance()->Clean(); // Experimental hall is a 40 meters box detector queen; queen.name = "root"; queen.mother = "akasha"; queen.description = "mother of us all"; queen.pos = G4ThreeVector(0, 0, 0); queen.rot = G4RotationMatrix(G4ThreeVector(1, 0, 0), G4ThreeVector(0, 1, 0), G4ThreeVector(0, 0, 1)); queen.type = "Box"; queen.dimensions.push_back(20*m); queen.dimensions.push_back(20*m); queen.dimensions.push_back(20*m); queen.material = hall_mat; queen.magfield = hall_field; queen.visible = 0; queen.ncopy = 0; queen.scanned = 1; queen.create_solid(gemcOpt, Hall_Map); queen.create_logical_volume(MMats, gemcOpt); queen.create_physical_volumes(gemcOpt, NULL); HasMagfield(queen, gemcOpt); (*Hall_Map)["root"] = queen; if(VERB > 3 || catch_v == "root") cout << hd_msg << " " << queen ; cout << hd_msg << " Building Detector from Geometry STL Map..." << endl << endl; // ###################################################### // Resetting Detector Map "scanned". Propagating "exist". // ###################################################### if(VERB > 2) cout << hd_msg << " Mapping Physical Detector..." << endl << endl; for( map::iterator i = Hall_Map->begin(); i!=Hall_Map->end(); i++) { if(VERB > 3) cout << hd_msg << " Scanning Detector " << i->first << endl; /* // Propagating "exist" flag to child - just in case if(i->second.mother != "akasha") if((*Hall_Map)[i->second.mother].exist == 0 && i->second.exist == 1) { if(VERB > 2) cout << hd_msg << "\t" << i->second.mother << " is not activated. Its child " << i->second.name << " will be disactivated as well." << endl; i->second.exist = 0; }*/ if(i->first != "root") i->second.scanned = 0; } if(VERB > 2) cout << endl; // ######################################################################## // Building Solids, Logical Volumes, Physical Volumes from the detector Map // ######################################################################## vector relatives; string mom, kid; for( map::iterator i = Hall_Map->begin(); i!=Hall_Map->end(); i++) { if(i->first != "root") relatives.push_back(i->second.name); while(relatives.size() > 0) { mom = (*Hall_Map)[relatives.back()].mother; kid = (*Hall_Map)[relatives.back()].name; // Mom doesn't exists in the map. Stopping everything. if((*Hall_Map)[mom].name == "" && mom != "akasha" && (*Hall_Map)[mom].scanned == 0) { cout << hd_msg << " Mom <" << mom << "> does not exist for <" << kid << ">. We have a No Child Left Behind policy. Exiting. " << endl << endl; exit(0); } if(VERB > 3 || kid.find(catch_v) != string::npos) { for(int i=0; i 3 || kid.find(catch_v) != string::npos) { for(int i=0; i 3 || kid.find(catch_v) != string::npos) cout << hd_msg << " " << kid << " is built." << endl << endl; relatives.pop_back(); } } } G4OpticalSurface* Mirror_Surface = new G4OpticalSurface("ScintSurface"); Mirror_Surface->SetType(dielectric_metal); Mirror_Surface->SetFinish(polished); Mirror_Surface->SetModel(unified); const G4int nEntries_Mirror = 2; G4double PhotonEnergy_Mirror[nEntries_Mirror] = { 2.034*eV, 4.136*eV }; G4double Reflectivity_Mirror[nEntries_Mirror] = {0.99, 0.99}; G4MaterialPropertiesTable* Mirror_MPT = new G4MaterialPropertiesTable(); Mirror_MPT->AddProperty("REFLECTIVITY", PhotonEnergy_Mirror, Reflectivity_Mirror, nEntries_Mirror); Mirror_Surface->SetMaterialPropertiesTable(Mirror_MPT); // G4LogicalBorderSurface* Mirror = new G4LogicalBorderSurface("Mirror", // (*Hall_Map)["root"].GetPhysical(), // (*Hall_Map)["Mirror"].GetPhysical(), Mirror_Surface); return (*Hall_Map)["root"].GetPhysical(); } #include "G4UserLimits.hh" void MDetectorConstruction::IsSensitive(detector detect, gemc_opts Opts) { string hd_msg = gemcOpt.args["LOG_MSG"].args + " Sensitivity: >> "; double VERB = gemcOpt.args["HIT_VERBOSITY"].arg ; string catch_v = gemcOpt.args["CATCH"].args; string sensi = detect.sensitivity; if(sensi != "no") { // Sensitive_region->AddRootLogicalVolume(detect.GetLogical()); G4SDManager* SDman = G4SDManager::GetSDMpointer(); if (!SDman) throw "Can't get G4SDManager"; if(VERB > 5 || detect.name.find(catch_v) != string::npos) cout << hd_msg << " " << detect.name << " is sensitive." << endl; // The key for the SD, Region, PC maps is the same so we can only check SD map::iterator itr = SeDe_Map.find(sensi); if(itr == SeDe_Map.end()) { if(VERB > 3 || detect.name.find(catch_v) != string::npos) cout << endl << hd_msg << " Sensitive detector <" << sensi << "> doesn't exist yet. Adding <" << sensi << ">. " << endl; SeDe_Map[sensi] = new MSensitiveDetector(sensi, gemcOpt); // Creating G4 Region, assigning Production Cut to it. SeRe_Map[sensi] = new G4Region(sensi); SePC_Map[sensi] = new G4ProductionCuts; SePC_Map[sensi] ->SetProductionCut(SeDe_Map[sensi]->SDID.ProdThreshold); SeRe_Map[sensi]->SetProductionCuts(SePC_Map[sensi]); if(VERB > 3 || detect.name.find(catch_v) != string::npos) cout << hd_msg << " Max Step for Sensitive detector <" << sensi << ">: " << SeDe_Map[sensi]->SDID.MaxStep/mm << " mm." << endl << hd_msg << " Production Cut for Sensitive detector <" << sensi << ">: " << SeDe_Map[sensi]->SDID.ProdThreshold/mm << " mm." << endl << endl; // Pass Detector Map Pointer to Sensitive Detector SeDe_Map[sensi]->Hall_Map = Hall_Map; SDman->AddNewDetector( SeDe_Map[sensi]); } detect.setSensitivity(SeDe_Map[sensi]); // Setting Max Acceptable Step for this SD detect.SetUserLimits(new G4UserLimits(SeDe_Map[sensi]->SDID.MaxStep)); map::iterator itrRE = SeRe_Map.find(sensi); SeRe_Map[sensi]->AddRootLogicalVolume(detect.GetLogical()); } } void MDetectorConstruction::HasMagfield(detector detect, gemc_opts Opts) { string hd_msg = gemcOpt.args["LOG_MSG"].args + " Magnetic Field: >> "; double VERB = gemcOpt.args["MGN_VERBOSITY"].arg ; string catch_v = gemcOpt.args["CATCH"].args; string magf = detect.magfield; if(magf != "no") { if(VERB > 5 || detect.name.find(catch_v) != string::npos) cout << hd_msg << " " << detect.name << " is inside " << magf << " magnetic field." << endl; map::iterator itr = FieldMap->find(magf); if(itr == FieldMap->end()) { cout << hd_msg << " Magnetic Field <" << magf << "> is not defined. Exiting." << endl; exit(0); } if(itr->second.get_MFM() == NULL) { cout << hd_msg << " Magnetic Field <" << magf << "> doesn't exist yet. Adding <" << magf << ">. " << endl; itr->second.create_MFM(); } if(itr->second.get_MFM() != NULL) { detect.AssignMFM(itr->second.get_MFM()); if(VERB > 6 || detect.name.find(catch_v) != string::npos) cout << hd_msg << " Field <" << magf << "> assigned to " << detect.name << " " << detect.GetLogical() << endl; } } } void MDetectorConstruction::UpdateGeometry() { cout << "Updating geometry... " << endl; G4RunManager::GetRunManager()->GeometryHasBeenModified(); }