From bb496cacf00262226c9b7ae2caf7e7f41159b815 Mon Sep 17 00:00:00 2001 From: soleti Date: Tue, 6 Feb 2024 15:25:18 +0100 Subject: [PATCH 1/4] cigar geometry --- source/geometries/Cigar.cc | 352 ++++++++++++++++++ source/geometries/Cigar.config.mac | 21 ++ source/geometries/Cigar.h | 60 +++ source/geometries/Cigar.init.mac | 26 ++ source/geometries/GenericSquarePhotosensor.cc | 257 +++++++++++++ source/geometries/GenericSquarePhotosensor.h | 117 ++++++ source/materials/OpticalMaterialProperties.cc | 6 +- source/materials/OpticalMaterialProperties.h | 3 +- 8 files changed, 839 insertions(+), 3 deletions(-) create mode 100644 source/geometries/Cigar.cc create mode 100644 source/geometries/Cigar.config.mac create mode 100644 source/geometries/Cigar.h create mode 100644 source/geometries/Cigar.init.mac create mode 100644 source/geometries/GenericSquarePhotosensor.cc create mode 100644 source/geometries/GenericSquarePhotosensor.h diff --git a/source/geometries/Cigar.cc b/source/geometries/Cigar.cc new file mode 100644 index 000000000..99daf2353 --- /dev/null +++ b/source/geometries/Cigar.cc @@ -0,0 +1,352 @@ +// ---------------------------------------------------------------------------- +// nexus | Cigar.cc +// +// Box containing optical fibers +// +// The NEXT Collaboration +// ---------------------------------------------------------------------------- + +#include "Cigar.h" + +#include "FactoryBase.h" +#include "OpticalMaterialProperties.h" +#include "Visibilities.h" +#include "GenericSquarePhotosensor.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace nexus; + +REGISTER_CLASS(Cigar, GeometryBase) + +namespace nexus { + + Cigar::Cigar(): + GeometryBase(), + cigar_length_ (400 * mm), + cigar_width_ (30 * mm), + fiber_diameter_(1 * mm), + gas_("Ar"), + pressure_(1. * bar), + coating_ ("TPB"), + fiber_type_ ("Y11"), + coated_(true) + { + msg_ = new G4GenericMessenger(this, "/Geometry/Cigar/", + "Control commands of geometry Cigar."); + + G4GenericMessenger::Command& width_cmd = + msg_->DeclareProperty("cigar_width", cigar_width_, + "Barrel fiber radius"); + width_cmd.SetUnitCategory("Length"); + + G4GenericMessenger::Command& length_cmd = + msg_->DeclareProperty("cigar_length", cigar_length_, + "Barrel fiber length"); + length_cmd.SetUnitCategory("Length"); + + G4GenericMessenger::Command& fiber_diameter_cmd = + msg_->DeclareProperty("fiber_diameter", fiber_diameter_, + "Fiber diameter"); + fiber_diameter_cmd.SetUnitCategory("Length"); + + msg_->DeclareProperty("gas", gas_, "Gas (Ar or Xe)"); + + G4GenericMessenger::Command& pressure_cmd = + msg_->DeclareProperty("pressure", pressure_, + "Vessel pressure"); + pressure_cmd.SetUnitCategory("Pressure"); + + msg_->DeclareProperty("coating", coating_, "Fiber coating (TPB or PTH)"); + msg_->DeclareProperty("fiber_type", fiber_type_, "Fiber type (Y11 or B2)"); + msg_->DeclareProperty("coated", coated_, "Coat fibers with WLS coating"); + + } + + + + Cigar::~Cigar() + { + delete msg_; + } + + + + void Cigar::Construct() + { + + G4cout << "[Cigar] *** Cigar geometry ***" << G4endl; + G4cout << "[Cigar] Using " << fiber_type_ << " fibers"; + if (coated_) + G4cout << " with " << coating_ << " coating"; + G4cout << G4endl; + + inside_cigar_ = new BoxPointSampler(cigar_width_, cigar_width_, cigar_length_, 0, G4ThreeVector(0, 0, 0)); + + world_z_ = cigar_length_ * 2; + world_xy_ = cigar_width_ * 2; + + G4Material *this_fiber = materials::PS(); + G4MaterialPropertiesTable *this_fiber_optical = nullptr; + if (fiber_type_ == "Y11") { + this_fiber_optical = opticalprops::Y11(); + } else if (fiber_type_ == "B2") { + this_fiber_optical = opticalprops::B2(); + } else { + G4Exception("[Cigar]", "Construct()", + FatalException, "Invalid fiber type, must be Y11 or B2"); + } + + G4Material *this_coating = nullptr; + G4MaterialPropertiesTable *this_coating_optical = nullptr; + if (coated_) { + if (coating_ == "TPB") { + this_coating = materials::TPB(); + this_coating_optical = opticalprops::TPB(); + } else if (coating_ == "TPH") { + this_coating = materials::TPH(); + this_coating_optical = opticalprops::TPH(); + } else { + G4Exception("[Cigar]", "Construct()", + FatalException, "Invalid coating, must be TPB or TPH"); + } + } + + fiber_ = new GenericWLSFiber(fiber_type_, true, true, fiber_diameter_, cigar_length_ + 7 * cm, true, coated_, this_coating, this_fiber, true); + + // WORLD ///////////////////////////////////////////////// + + G4Material* world_mat = nullptr; + + if (gas_ == "Ar") { + world_mat = materials::GAr(pressure_); + world_mat->SetMaterialPropertiesTable(opticalprops::GAr(1. / (68 * eV))); + } else if (gas_ == "Xe") { + world_mat = materials::GXe(pressure_); + world_mat->SetMaterialPropertiesTable(opticalprops::GXe(pressure_)); + } else { + G4Exception("[Cigar]", "Construct()", + FatalException, "Invalid gas, must be Ar or Xe"); + } + + G4Box* world_solid_vol = + new G4Box("WORLD", world_xy_/2., world_xy_/2., world_z_/2.); + + G4LogicalVolume* world_logic_vol = + new G4LogicalVolume(world_solid_vol, world_mat, "WORLD"); + world_logic_vol->SetVisAttributes(G4VisAttributes::GetInvisible()); + GeometryBase::SetLogicalVolume(world_logic_vol); + + // TEFLON PANELS //////////////////////////////////////////// + G4double panel_width = 2.5 * mm; + G4Box* teflon_panel = + new G4Box("TEFLON_PANEL", cigar_width_ / 2, panel_width / 2, cigar_length_ / 2); + G4Box* teflon_panel_up = + new G4Box("TEFLON_PANEL", cigar_width_ / 2, cigar_width_ / 2, panel_width / 2); + G4Material* teflon = G4NistManager::Instance()->FindOrBuildMaterial("G4_TEFLON"); + teflon->SetMaterialPropertiesTable(opticalprops::PTFE()); + G4LogicalVolume* teflon_logic = + new G4LogicalVolume(teflon_panel, teflon, "TEFLON"); + G4LogicalVolume* teflon_logic_up = + new G4LogicalVolume(teflon_panel_up, teflon, "TEFLON_UP"); + teflon_logic->SetVisAttributes(nexus::White()); + teflon_logic_up->SetVisAttributes(nexus::White()); + + G4OpticalSurface* opsur_teflon = + new G4OpticalSurface("TEFLON_OPSURF", unified, groundteflonair, dielectric_metal); + opsur_teflon->SetMaterialPropertiesTable(opticalprops::PTFE()); + + new G4LogicalSkinSurface("TEFLON_OPSURF", teflon_logic, opsur_teflon); + + new G4PVPlacement(0, G4ThreeVector(0, cigar_width_/2+panel_width/2+fiber_diameter_, 0), + teflon_logic, "TEFLON1", world_logic_vol, + true, 0, false); + + new G4PVPlacement(0, G4ThreeVector(0, -cigar_width_/2-panel_width/2-fiber_diameter_, 0), + teflon_logic, "TEFLON2", world_logic_vol, + true, 1, false); + + new G4PVPlacement(0, G4ThreeVector(0, 0, cigar_length_/2+panel_width/2), + teflon_logic_up, "TEFLON3", world_logic_vol, + true, 1, false); + + new G4PVPlacement(0, G4ThreeVector(0, 0, -cigar_length_/2-panel_width/2), + teflon_logic_up, "TEFLON3", world_logic_vol, + true, 1, false); + + G4RotationMatrix *rot_x = new G4RotationMatrix(); + rot_x->rotateZ(90 * deg); + new G4PVPlacement(G4Transform3D(*rot_x, G4ThreeVector(cigar_width_ / 2 + panel_width / 2 + fiber_diameter_, 0, 0)), + teflon_logic, "TEFLON3", world_logic_vol, + true, 1, false); + + new G4PVPlacement(G4Transform3D(*rot_x, G4ThreeVector(-cigar_width_ / 2 - panel_width / 2 - fiber_diameter_, 0, 0)), + teflon_logic, "TEFLON4", world_logic_vol, + true, 1, false); + + // // FIBER //////////////////////////////////////////////////// + + fiber_->SetCoreOpticalProperties(this_fiber_optical); + fiber_->SetCoatingOpticalProperties(this_coating_optical); + + fiber_->Construct(); + G4LogicalVolume *fiber_logic = fiber_->GetLogicalVolume(); + if (fiber_type_ == "Y11") + fiber_logic->SetVisAttributes(nexus::LightGreenAlpha()); + else if (fiber_type_ == "B2") + fiber_logic->SetVisAttributes(nexus::LightBlueAlpha()); + + G4int n_fibers = floor(cigar_width_ / fiber_diameter_); + G4cout << "[Cigar] Box with " << n_fibers << " fibers each side" << G4endl; + + // // DETECTOR ///////////////////////////////////////////// + G4double photosensor_thickness = 0.4 * mm; + GenericSquarePhotosensor *sipm = new GenericSquarePhotosensor("FIBER_SENSOR", fiber_diameter_, n_fibers * fiber_diameter_, photosensor_thickness); + G4int sipm_entries = 24; + G4double sipm_energy[] = { + h_Planck * c_light / (866.20 * nm), h_Planck * c_light / (808.45 * nm), + h_Planck * c_light / (766.20 * nm), h_Planck * c_light / (721.13 * nm), + h_Planck * c_light / (685.92 * nm), h_Planck * c_light / (647.89 * nm), + h_Planck * c_light / (623.94 * nm), h_Planck * c_light / (597.18 * nm), + h_Planck * c_light / (573.24 * nm), h_Planck * c_light / (545.07 * nm), + h_Planck * c_light / (518.31 * nm), h_Planck * c_light / (502.82 * nm), + h_Planck * c_light / (454.93 * nm), h_Planck * c_light / (421.13 * nm), + h_Planck * c_light / (395.77 * nm), h_Planck * c_light / (378.87 * nm), + h_Planck * c_light / (367.61 * nm), h_Planck * c_light / (359.15 * nm), + h_Planck * c_light / (349.30 * nm), h_Planck * c_light / (340.85 * nm), + h_Planck * c_light / (336.62 * nm), h_Planck * c_light / (332.39 * nm), + h_Planck * c_light / (326.76 * nm), h_Planck * c_light / (319.72 * nm) + }; + + G4double sipm_efficiency[] = { + 5.75, 9.38, + 12.48, 16.37, + 20.18, 24.34, + 28.67, 33.01, + 37.26, 41.50, + 45.93, 48.32, + 50.00, 47.61, + 43.54, 39.03, + 34.25, 29.91, + 25.40, 20.62, + 16.02, 11.50, + 6.81, 3.36 + }; + for (G4int i=0; i < sipm_entries; i++) { + sipm_efficiency[i] /= 100; + } + G4double energy[] = {opticalprops::optPhotMinE_, opticalprops::optPhotMaxE_}; + G4double reflectivity[] = {0.0 , 0.0 }; + G4double efficiency[] = {1. , 1. }; + G4MaterialPropertiesTable* photosensor_mpt = new G4MaterialPropertiesTable(); + photosensor_mpt->AddProperty("REFLECTIVITY", energy, reflectivity, 2); + photosensor_mpt->AddProperty("EFFICIENCY", sipm_energy, sipm_efficiency, sipm_entries); + sipm->SetOpticalProperties(photosensor_mpt); + sipm->SetVisibility(true); + sipm->SetSensorDepth(1); + sipm->SetTimeBinning(50 * ns); + sipm->SetWindowRefractiveIndex(opticalprops::OptCoupler()->GetProperty("RINDEX")); + sipm->Construct(); + G4LogicalVolume* sipm_logic = sipm->GetLogicalVolume(); + // // ALUMINIZED ENDCAP + + G4Material *fiber_end_mat = G4NistManager::Instance()->FindOrBuildMaterial("G4_Al"); + + G4double fiber_end_z = 350 * nm; + + G4Tubs *fiber_end_solid_vol = + new G4Tubs("fiber_end", 0, fiber_diameter_ / 2, fiber_end_z, 0, 2 * M_PI); + + G4LogicalVolume *fiber_end_logic_vol = + new G4LogicalVolume(fiber_end_solid_vol, fiber_end_mat, "FIBER_END"); + G4OpticalSurface *opsur_al = + new G4OpticalSurface("AL_OPSURF", glisur, ground, dielectric_metal); + opsur_al->SetPolish(0.75); + opsur_al->SetMaterialPropertiesTable(opticalprops::PolishedAl()); + + new G4LogicalSkinSurface("AL_OPSURF", fiber_end_logic_vol, opsur_al); + + // // PLACEMENT ///////////////////////////////////////////// + G4RotationMatrix *rot_y = new G4RotationMatrix(); + rot_y->rotateY(180 * deg); + new G4PVPlacement(G4Transform3D(*rot_y, G4ThreeVector(cigar_width_ / 2 + fiber_diameter_ / 2, 0, cigar_length_ / 2 + photosensor_thickness / 2 + 7 * cm)), + sipm_logic, "SIPM1", world_logic_vol, + false, 1, false); + + new G4PVPlacement(G4Transform3D(*rot_y, G4ThreeVector(- cigar_width_ / 2 - fiber_diameter_ / 2, 0, cigar_length_ / 2 + photosensor_thickness / 2 + 7 * cm)), + sipm_logic, "SIPM2", world_logic_vol, + false, 2, false); + rot_y->rotateZ(90 * deg); + new G4PVPlacement(G4Transform3D(*rot_y, G4ThreeVector(0, - cigar_width_ / 2 - fiber_diameter_ / 2, cigar_length_ / 2 + photosensor_thickness / 2 + 7 * cm)), + sipm_logic, "SIPM3", world_logic_vol, + false, 3, false); + new G4PVPlacement(G4Transform3D(*rot_y, G4ThreeVector(0, cigar_width_ / 2 + fiber_diameter_ / 2, cigar_length_ / 2 + photosensor_thickness / 2 + 7 * cm)), + sipm_logic, "SIPM4", world_logic_vol, + false, 4, false); + for (G4int ifiber = 0; ifiber < n_fibers; ifiber++) + { + + std::string label = std::to_string(ifiber); + + new G4PVPlacement(0, G4ThreeVector(cigar_width_ / 2 + fiber_diameter_ / 2, -cigar_width_ / 2 + ifiber * fiber_diameter_ + fiber_diameter_ / 2, 3.5 * cm), + fiber_logic, "FIBER1-" + label, world_logic_vol, + true, ifiber, false); + + new G4PVPlacement(0, G4ThreeVector(-cigar_width_ / 2 - fiber_diameter_ / 2, -cigar_width_ / 2 + ifiber * fiber_diameter_ + fiber_diameter_ / 2, 3.5 * cm), + fiber_logic, "FIBER2-" + label, world_logic_vol, + true, ifiber * 2, false); + + new G4PVPlacement(0, G4ThreeVector(-cigar_width_ / 2 + ifiber * fiber_diameter_ + fiber_diameter_ / 2, -cigar_width_ / 2 - fiber_diameter_ / 2, 3.5 * cm), + fiber_logic, "FIBER3-" + label, world_logic_vol, + true, ifiber * 3, false); + + new G4PVPlacement(0, G4ThreeVector(-cigar_width_ / 2 + ifiber * fiber_diameter_ + fiber_diameter_ / 2, cigar_width_ / 2 + fiber_diameter_ / 2, 3.5 * cm), + fiber_logic, "FIBER4-" + label, world_logic_vol, + true, ifiber * 4, false); + + new G4PVPlacement(0, G4ThreeVector(cigar_width_ / 2 + fiber_diameter_ / 2, -cigar_width_ / 2 + ifiber * fiber_diameter_ + fiber_diameter_ / 2, -cigar_length_ / 2 - fiber_end_z), + fiber_end_logic_vol, "ALUMINUM1-" + label, world_logic_vol, + true, ifiber, false); + + new G4PVPlacement(0, G4ThreeVector(-cigar_width_ / 2 - fiber_diameter_ / 2, -cigar_width_ / 2 + ifiber * fiber_diameter_ + fiber_diameter_ / 2, -cigar_length_ / 2 - fiber_end_z), + fiber_end_logic_vol, "ALUMINUM2-" + label, world_logic_vol, + true, ifiber, false); + + new G4PVPlacement(0, G4ThreeVector(-cigar_width_ / 2 + ifiber * fiber_diameter_ + fiber_diameter_ / 2, -cigar_width_ / 2 - fiber_diameter_ / 2, -cigar_length_ / 2 - fiber_end_z), + fiber_end_logic_vol, "ALUMINUM3-" + label, world_logic_vol, + true, ifiber, false); + + new G4PVPlacement(0, G4ThreeVector(-cigar_width_ / 2 + ifiber * fiber_diameter_ + fiber_diameter_ / 2, cigar_width_ / 2 + fiber_diameter_ / 2, -cigar_length_ / 2 - fiber_end_z), + fiber_end_logic_vol, "ALUMINUM4-" + label, world_logic_vol, + true, ifiber, false); + } + + } + + + + G4ThreeVector Cigar::GenerateVertex(const G4String& region) const + { + G4ThreeVector vertex(0.,0.,0.); + + // WORLD + if (region == "INSIDE_CIGAR") { + // return vertex; + return inside_cigar_->GenerateVertex("INSIDE"); + } + else { + G4Exception("[Cigar]", "GenerateVertex()", FatalException, + "Unknown vertex generation region!"); + } + return vertex; + } + + +} // end namespace nexus \ No newline at end of file diff --git a/source/geometries/Cigar.config.mac b/source/geometries/Cigar.config.mac new file mode 100644 index 000000000..5d9aedde1 --- /dev/null +++ b/source/geometries/Cigar.config.mac @@ -0,0 +1,21 @@ +#/Generator/SingleParticle/particle opticalphoton +#/Generator/SingleParticle/min_energy 7 eV +#/Generator/SingleParticle/max_energy 7 eV +#/Generator/SingleParticle/region INSIDE_CIGAR +/Generator/Kr83mGenerator/region INSIDE_CIGAR + +/Geometry/Cigar/pressure 1 bar +/Geometry/Cigar/fiber_diameter 1 mm +/Geometry/Cigar/coating TPB +/Geometry/Cigar/fiber_type Y11 +/Geometry/Cigar/gas Xe + +/run/verbose 1 +/event/verbose 0 +/tracking/verbose 0 +/process/em/verbose 0 + +### JOB CONTROL +/nexus/random_seed 1 +/nexus/persistency/start_id 0 +/nexus/persistency/outputFile Cigar.next diff --git a/source/geometries/Cigar.h b/source/geometries/Cigar.h new file mode 100644 index 000000000..9d7cdb322 --- /dev/null +++ b/source/geometries/Cigar.h @@ -0,0 +1,60 @@ +// ---------------------------------------------------------------------------- +// nexus | Cigar.h +// +// Box-shaped box of material with a coating. +// +// The NEXT Collaboration +// ---------------------------------------------------------------------------- + +#ifndef Cigar_H +#define Cigar_H + +#include "GeometryBase.h" +#include "GenericWLSFiber.h" +#include "PmtR11410.h" +#include "BoxPointSampler.h" +#include "MaterialsList.h" + +class G4Material; +class G4GenericMessenger; +namespace nexus { class SpherePointSampler; } + + +namespace nexus { + + /// Spherical chamber filled with xenon (liquid or gas) + + class Cigar: public GeometryBase + { + public: + /// Constructor + Cigar(); + /// Destructor + ~Cigar(); + + /// Return vertex within region of the chamber + G4ThreeVector GenerateVertex(const G4String& region) const; + + void Construct(); + + private: + G4double world_z_; // World dimensions + G4double world_xy_; + G4double cigar_length_; + G4double cigar_width_; + G4double fiber_diameter_; + G4String gas_; + G4double pressure_; + G4String coating_; + G4String fiber_type_; + G4bool coated_; + + GenericWLSFiber* fiber_; + BoxPointSampler* inside_cigar_; + /// Messenger for the definition of control commands + G4GenericMessenger* msg_; + }; + +} // end namespace nexus + +#endif \ No newline at end of file diff --git a/source/geometries/Cigar.init.mac b/source/geometries/Cigar.init.mac new file mode 100644 index 000000000..c634db827 --- /dev/null +++ b/source/geometries/Cigar.init.mac @@ -0,0 +1,26 @@ +### -------------------------------------------------------- +### This init macro simulates the response of a SensL SiPM DICE +### board in the black box. +### -------------------------------------------------------- + +/control/execute macros/physics/DefaultPhysicsList.mac +/tracking/verbose 1 +/nexus/RegisterGeometry Cigar +#/nexus/RegisterGenerator SingleParticleGenerator +/nexus/RegisterGenerator Kr83mGenerator +/nexus/RegisterPersistencyManager PersistencyManager + +/PhysicsList/RegisterPhysics G4EmStandardPhysics_option4 +/PhysicsList/RegisterPhysics G4DecayPhysics +/PhysicsList/RegisterPhysics G4RadioactiveDecayPhysics +#/PhysicsList/RegisterPhysics G4OpticalPhysics +/PhysicsList/RegisterPhysics NexusPhysics +/PhysicsList/RegisterPhysics G4StepLimiterPhysics +### ACTIONS + +/nexus/RegisterRunAction DefaultRunAction +/nexus/RegisterTrackingAction DefaultTrackingAction +#/nexus/RegisterTrackingAction OpticalTrackingAction +/nexus/RegisterSteppingAction AnalysisSteppingAction + +/nexus/RegisterMacro macros/Cigar.config.mac diff --git a/source/geometries/GenericSquarePhotosensor.cc b/source/geometries/GenericSquarePhotosensor.cc new file mode 100644 index 000000000..383a73b48 --- /dev/null +++ b/source/geometries/GenericSquarePhotosensor.cc @@ -0,0 +1,257 @@ +// ----------------------------------------------------------------------------- +// nexus | GenericSquarePhotosensor.cc +// +// Geometry of a configurable box-shaped photosensor. +// +// The NEXT Collaboration +// ----------------------------------------------------------------------------- + +#include "GenericSquarePhotosensor.h" + +#include "MaterialsList.h" +#include "SensorSD.h" +#include "OpticalMaterialProperties.h" +#include "Visibilities.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace nexus; + + +GenericSquarePhotosensor::GenericSquarePhotosensor(G4String name, + G4double width, + G4double height, + G4double thickness): + GeometryBase (), + name_ (name), + width_ (width), // Width of the Sensitive Area + height_ (height), // Height of the Sensitive Area + thickness_ (thickness), // Thickness of the whole sensor + window_thickness_ (0.3 * mm), // Window thickness (similar to Sensl SiPMs) + sensarea_thickness_ (0.1 * mm), // Sensitive thickness (similar to Sensl SiPMs) + wls_thickness_ (1. * micrometer), // WLS thickness = 1 micron by definition) + with_wls_coating_ (false), + window_rindex_ (nullptr), + sensitive_mpt_ (nullptr), + sensor_depth_ (-1), + mother_depth_ (0), + naming_order_ (0), + time_binning_ (1.0 * us), + visibility_ (false) +{ +} + + +GenericSquarePhotosensor::GenericSquarePhotosensor(G4String name, G4double size): + GenericSquarePhotosensor(name, size, size) +{ +} + + +GenericSquarePhotosensor::~GenericSquarePhotosensor() +{ +} + + +void GenericSquarePhotosensor::ComputeDimensions() +{ + // Reduced size for components inside the case except the WLS + reduced_width_ = width_ - 1. * micrometer; + reduced_height_ = height_ - 1. * micrometer; + + if (!with_wls_coating_) wls_thickness_ = 0.; + + // Check that components (window + sensitive + wls) fits into the case + if ((window_thickness_ + sensarea_thickness_ + wls_thickness_) > thickness_) { + G4Exception("[GenericSquarePhotosensor]", "ComputeDimensions()", FatalException, + ("Sensor size too small. Required thickness >= " + + std::to_string(window_thickness_ + sensarea_thickness_ + wls_thickness_) + + " mm").data()); + } +} + + +void GenericSquarePhotosensor::DefineMaterials() +{ + // Case ///// + case_mat_ = materials::FR4(); + case_mat_->SetMaterialPropertiesTable(new G4MaterialPropertiesTable()); + + // Window ///// + // The optical properties of a given material, is common for the whole geometry so, + // making a copy of the window material restricts its use to this photosensor + // and prevents interferences with other possible uses. + window_mat_ = + materials::CopyMaterial(materials::OpticalSilicone(), + name_ + "_WINDOW_MATERIAL"); + G4MaterialPropertiesTable* window_optProp = new G4MaterialPropertiesTable(); + + // In the default behavior of this class, the refractive index of WLS and window + // are matched to avoid reflection losses in the interfaces. If the user sets + // explicitly a refractive index for the window, it won't be used, raising a warning. + if (with_wls_coating_) { + if (window_rindex_) + G4Exception("[GenericSquarePhotosensor]", "DefineMaterials()", JustWarning, + "Window rindex set, but NOT USED. Using TPB rindex."); + + window_optProp->AddProperty("RINDEX", + opticalprops::TPB()->GetProperty("RINDEX")); + window_mat_->SetMaterialPropertiesTable(window_optProp); + } + + // If the sensor has NOT WLS coating the window must have the rindex + // set by the user. If it is not set, an exception raises. + else { + if (!window_rindex_) + G4Exception("[GenericSquarePhotosensor]", "DefineMaterials()", FatalException, + "Window rindex must be set before constructing"); + + window_optProp->AddProperty("RINDEX", window_rindex_); + window_mat_->SetMaterialPropertiesTable(window_optProp); + } + + // Sensitive ///// + sensitive_mat_ = G4NistManager::Instance()->FindOrBuildMaterial("G4_Si"); + sensitive_mat_->SetMaterialPropertiesTable(new G4MaterialPropertiesTable()); + + // WLS coating ///// + wls_mat_ = materials::TPB(); + wls_mat_->SetMaterialPropertiesTable(opticalprops::TPB()); +} + + +void GenericSquarePhotosensor::Construct() +{ + ComputeDimensions(); + + DefineMaterials(); + + // PHOTOSENSOR CASE ////////////////////////////////// + G4String name = name_ + "_CASE"; + + // G4Tubs* case_solid_vol = new G4Tubs(name, 0, width_ / 2., thickness_ / 2., 0, twopi); + G4Box* case_solid_vol = + new G4Box(name, width_/2. , height_/2. , thickness_/2.); + + G4LogicalVolume* case_logic_vol = + new G4LogicalVolume(case_solid_vol, case_mat_, name); + + GeometryBase::SetLogicalVolume(case_logic_vol); + + + // OPTICAL WINDOW //////////////////////////////////////// + name = name_ + "_WINDOW"; + + // G4Tubs* window_solid_vol = new G4Tubs(name, 0, reduced_width_ / 2., window_thickness_ / 2., 0, twopi); + + G4Box* window_solid_vol = + new G4Box(name, reduced_width_/2., reduced_height_/2., window_thickness_/2.); + + G4LogicalVolume* window_logic_vol = + new G4LogicalVolume(window_solid_vol, window_mat_, name); + + G4double window_zpos = thickness_/2. - wls_thickness_ - window_thickness_/2.; + + new G4PVPlacement(nullptr, G4ThreeVector(0., 0., window_zpos), window_logic_vol, + name, case_logic_vol, false, 0, false); + + + // PHOTOSENSITIVE AREA ///////////////////////////////////////////// + name = name_ + "_SENSAREA"; + + // G4Tubs* sensarea_solid_vol = new G4Tubs(name, 0, reduced_width_ / 2., sensarea_thickness_ / 2., 0, twopi); + + G4Box* sensarea_solid_vol = + new G4Box(name, reduced_width_/2., reduced_height_/2., sensarea_thickness_/2.); + + G4LogicalVolume* sensarea_logic_vol = + new G4LogicalVolume(sensarea_solid_vol, sensitive_mat_, name); + + G4double sensarea_zpos = thickness_/2. - wls_thickness_ - window_thickness_ - + sensarea_thickness_/2.; + + new G4PVPlacement(nullptr, G4ThreeVector(0., 0., sensarea_zpos), sensarea_logic_vol, + name, case_logic_vol, false, 0, false); + + + // WLS_COATING ///////////////////////////////////////////// + G4LogicalVolume* wls_logic_vol; + if (with_wls_coating_) { + name = name_ + "_WLS"; + + G4Box* wls_solid_vol = + new G4Box(name, width_/2., height_/2., wls_thickness_/2.); + + wls_logic_vol = new G4LogicalVolume(wls_solid_vol, wls_mat_, name); + + G4double wls_zpos = thickness_/2. - wls_thickness_/2.; + + new G4PVPlacement(nullptr, G4ThreeVector(0., 0., wls_zpos), wls_logic_vol, + name, case_logic_vol, false, 0, false); + + G4OpticalSurface* wls_optSurf = new G4OpticalSurface(name + "_OPSURF", + glisur, ground, + dielectric_dielectric, .01); + + new G4LogicalSkinSurface(name + "_OPSURF", wls_logic_vol, wls_optSurf); + + wls_logic_vol->SetVisAttributes(G4VisAttributes::GetInvisible()); + } + + + // VISIBILITIES ///////////////////////////////////////////// + if (visibility_) { + window_logic_vol->SetVisAttributes(nexus::LightBlueAlpha()); + sensarea_logic_vol->SetVisAttributes(nexus::DarkGrey()); + case_logic_vol->SetVisAttributes(G4VisAttributes::GetInvisible()); + } + else { + window_logic_vol ->SetVisAttributes(G4VisAttributes::GetInvisible()); + sensarea_logic_vol->SetVisAttributes(G4VisAttributes::GetInvisible()); + case_logic_vol->SetVisAttributes(G4VisAttributes::GetInvisible()); + } + + + // SENSOR OPTICAL PROPERTIES //////////////////////////////////////// + if (!sensitive_mpt_) + G4Exception("[GenericSquarePhotosensor]", "Construct()", FatalException, + "Sensor Optical Properties must be set before constructing"); + G4OpticalSurface* sensitive_opsurf = + new G4OpticalSurface(name + "_optSurf", unified, polished, dielectric_metal); + sensitive_opsurf->SetMaterialPropertiesTable(sensitive_mpt_); + new G4LogicalSkinSurface(name + "_optSurf", sensarea_logic_vol, sensitive_opsurf); + + + // SENSITIVE DETECTOR ////////////////////////////////////////////// + G4String sdname = "/GENERIC_PHOTOSENSOR/" + name_; + G4SDManager* sdmgr = G4SDManager::GetSDMpointer(); + + if (!sdmgr->FindSensitiveDetector(sdname, false)) { + SensorSD* sensdet = new SensorSD(sdname); + if (sensor_depth_ == -1) + G4Exception("[GenericSquarePhotosensor]", "Construct()", FatalException, + "Sensor Depth must be set before constructing"); + + if ((naming_order_ > 0) & (mother_depth_ == 0)) + G4Exception("[GenericSquarePhotosensor]", "Construct()", FatalException, + "naming_order set without setting mother_depth"); + + sensdet->SetDetectorVolumeDepth(sensor_depth_); + sensdet->SetMotherVolumeDepth (mother_depth_); + sensdet->SetDetectorNamingOrder(naming_order_); + sensdet->SetTimeBinning (time_binning_); + + G4SDManager::GetSDMpointer()->AddNewDetector(sensdet); + sensarea_logic_vol->SetSensitiveDetector(sensdet); + } +} diff --git a/source/geometries/GenericSquarePhotosensor.h b/source/geometries/GenericSquarePhotosensor.h new file mode 100644 index 000000000..5d6c13a06 --- /dev/null +++ b/source/geometries/GenericSquarePhotosensor.h @@ -0,0 +1,117 @@ +// ----------------------------------------------------------------------------- +// nexus | GenericSquarePhotosensor.h +// +// Geometry of a configurable box-shaped photosensor. +// +// The NEXT Collaboration +// ----------------------------------------------------------------------------- + +#ifndef GENERIC_SQUAREPHOTOSENSOR_H +#define GENERIC_SQUAREPHOTOSENSOR_H + +#include "GeometryBase.h" +#include + +class G4Material; +class G4GenericMessenger; +class G4MaterialPropertiesTable; + +namespace nexus { + + class GenericSquarePhotosensor: public GeometryBase + { + public: + // Constructor for a rectangular sensor providing + // The default thickness corresponds to a typical value for + // a silicon photomultiplier. + GenericSquarePhotosensor(G4String name, G4double width, + G4double height, G4double thickness = 2.0 * mm); + + // Constructor for a square sensor + GenericSquarePhotosensor(G4String name, G4double size); + + // Destructor + ~GenericSquarePhotosensor(); + + // + void Construct(); + + // + G4double GetWidth() const; + G4double GetHeight() const; + G4double GetThickness() const; + const G4String& GetName() const; + + void SetVisibility (G4bool visibility); + void SetWithWLSCoating (G4bool with_wls_coating); + void SetWindowRefractiveIndex(G4MaterialPropertyVector* rindex); + void SetOpticalProperties (G4MaterialPropertiesTable* mpt); + void SetTimeBinning (G4double time_binning); + void SetSensorDepth (G4int sensor_depth); + void SetMotherDepth (G4int mother_depth); + void SetNamingOrder (G4int naming_order); + + private: + + void ComputeDimensions(); + void DefineMaterials(); + + G4String name_; + + G4double width_, height_, thickness_; + G4double window_thickness_; + G4double sensarea_thickness_; + G4double wls_thickness_; + G4double reduced_width_, reduced_height_; + + G4Material* case_mat_; + G4Material* window_mat_; + G4Material* sensitive_mat_; + G4Material* wls_mat_; + + G4bool with_wls_coating_; + G4MaterialPropertyVector* window_rindex_; + G4MaterialPropertiesTable* sensitive_mpt_; + + G4int sensor_depth_; + G4int mother_depth_; + G4int naming_order_; + G4double time_binning_; + + G4bool visibility_; + }; + + + inline G4double GenericSquarePhotosensor::GetWidth() const { return width_; } + inline G4double GenericSquarePhotosensor::GetHeight() const { return height_; } + inline G4double GenericSquarePhotosensor::GetThickness() const { return thickness_; } + inline const G4String& GenericSquarePhotosensor::GetName() const { return name_; } + + inline void GenericSquarePhotosensor::SetVisibility(G4bool visibility) + { visibility_ = visibility; } + + inline void GenericSquarePhotosensor::SetWithWLSCoating(G4bool with_wls_coating) + { with_wls_coating_ = with_wls_coating; } + + inline void GenericSquarePhotosensor::SetWindowRefractiveIndex(G4MaterialPropertyVector* rindex) + { window_rindex_ = rindex; } + + inline void GenericSquarePhotosensor::SetOpticalProperties(G4MaterialPropertiesTable* mpt) + { sensitive_mpt_ = mpt; } + + inline void GenericSquarePhotosensor::SetTimeBinning(G4double time_binning) + { time_binning_ = time_binning; } + + inline void GenericSquarePhotosensor::SetSensorDepth(G4int sensor_depth) + { sensor_depth_ = sensor_depth; } + + inline void GenericSquarePhotosensor::SetMotherDepth(G4int mother_depth) + { mother_depth_ = mother_depth; } + + inline void GenericSquarePhotosensor::SetNamingOrder(G4int naming_order) + { naming_order_ = naming_order; } + + +} // namespace nexus + +#endif diff --git a/source/materials/OpticalMaterialProperties.cc b/source/materials/OpticalMaterialProperties.cc index f331c4d7a..fa5542fa7 100644 --- a/source/materials/OpticalMaterialProperties.cc +++ b/source/materials/OpticalMaterialProperties.cc @@ -936,7 +936,8 @@ namespace opticalprops { hc_ / (300. * nm), hc_ / (270. * nm), hc_ / (250. * nm), hc_ / (230. * nm), hc_ / (210. * nm), hc_ / (190. * nm), hc_ / (170. * nm), hc_ / (150. * nm), - optPhotMaxE_ + hc_ / (96. * nm), + optPhotTPBMaxE_ }; std::vector WLS_absLength = { @@ -945,7 +946,8 @@ namespace opticalprops { 30. * nm, 50. * nm, 80. * nm, // 330, 320, 310 nm 100. * nm, 100. * nm, 400. * nm, // 300, 270, 250 nm 400. * nm, 350. * nm, 250. * nm, // 230, 210, 190 nm - 350. * nm, 400. * nm, 400. * nm // 170, 150, ~108 nm + 350. * nm, 400. * nm, 400. * nm, // 170, 150, ~108 nm + noAbsLength_ }; //for (int i=0; i Date: Tue, 6 Feb 2024 15:25:39 +0100 Subject: [PATCH 2/4] cigar macro --- macros/Cigar.config.mac | 21 +++++++++++++++++++++ macros/Cigar.init.mac | 26 ++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 macros/Cigar.config.mac create mode 100644 macros/Cigar.init.mac diff --git a/macros/Cigar.config.mac b/macros/Cigar.config.mac new file mode 100644 index 000000000..3d477d047 --- /dev/null +++ b/macros/Cigar.config.mac @@ -0,0 +1,21 @@ +#/Generator/SingleParticle/particle opticalphoton +#/Generator/SingleParticle/min_energy 7 eV +#/Generator/SingleParticle/max_energy 7 eV +#/Generator/SingleParticle/region INSIDE_CIGAR +/Generator/Kr83mGenerator/region INSIDE_CIGAR + +/Geometry/Cigar/pressure 1 bar +/Geometry/Cigar/fiber_diameter 1 mm +/Geometry/Cigar/coating TPB +/Geometry/Cigar/fiber_type Y11 +/Geometry/Cigar/gas Xe + +/run/verbose 1 +/event/verbose 0 +/tracking/verbose 0 +/process/em/verbose 0 + +### JOB CONTROL +/nexus/random_seed 1 +/nexus/persistency/start_id 0 +/nexus/persistency/output_file Cigar.next diff --git a/macros/Cigar.init.mac b/macros/Cigar.init.mac new file mode 100644 index 000000000..2d66b6f43 --- /dev/null +++ b/macros/Cigar.init.mac @@ -0,0 +1,26 @@ +### -------------------------------------------------------- +### This init macro simulates the response of a SensL SiPM DICE +### board in the black box. +### -------------------------------------------------------- + +/control/execute macros/physics/DefaultPhysicsList.mac +/tracking/verbose 1 +/nexus/RegisterGeometry Cigar +#/nexus/RegisterGenerator SingleParticleGenerator +/nexus/RegisterGenerator Kr83mGenerator +/nexus/RegisterPersistencyManager PersistencyManager + +/PhysicsList/RegisterPhysics G4EmStandardPhysics_option4 +/PhysicsList/RegisterPhysics G4DecayPhysics +/PhysicsList/RegisterPhysics G4RadioactiveDecayPhysics +/PhysicsList/RegisterPhysics G4OpticalPhysics +/PhysicsList/RegisterPhysics NexusPhysics +/PhysicsList/RegisterPhysics G4StepLimiterPhysics +### ACTIONS + +/nexus/RegisterRunAction DefaultRunAction +/nexus/RegisterTrackingAction DefaultTrackingAction +/nexus/RegisterTrackingAction OpticalTrackingAction +/nexus/RegisterSteppingAction AnalysisSteppingAction + +/nexus/RegisterMacro macros/Cigar.config.mac From d673e4c314d1413fdd3fa9daeb7ba4a929bc05f3 Mon Sep 17 00:00:00 2001 From: soleti Date: Fri, 9 Feb 2024 10:18:50 +0100 Subject: [PATCH 3/4] fix wls args --- source/geometries/Cigar.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/geometries/Cigar.cc b/source/geometries/Cigar.cc index 99daf2353..82b98703a 100644 --- a/source/geometries/Cigar.cc +++ b/source/geometries/Cigar.cc @@ -119,7 +119,7 @@ namespace nexus { } } - fiber_ = new GenericWLSFiber(fiber_type_, true, true, fiber_diameter_, cigar_length_ + 7 * cm, true, coated_, this_coating, this_fiber, true); + fiber_ = new GenericWLSFiber(fiber_type_, true, true, fiber_diameter_, cigar_length_ + 7 * cm, true, coated_, this_fiber, this_coating, true); // WORLD ///////////////////////////////////////////////// From 6ca3308725489b3fb946534f6e03452609a8d0a4 Mon Sep 17 00:00:00 2001 From: MarcSeemann Date: Thu, 20 Jun 2024 10:50:01 +0200 Subject: [PATCH 4/4] Improved geometry --- macros/Cigar.config.mac | 2 +- running_nexus.sh | 64 +++++++++ source/geometries/Cigar.cc | 266 +++++++++++++++++++++++++++++-------- source/geometries/Cigar.h | 4 +- 4 files changed, 280 insertions(+), 56 deletions(-) create mode 100644 running_nexus.sh diff --git a/macros/Cigar.config.mac b/macros/Cigar.config.mac index 3d477d047..0c94bc6c8 100644 --- a/macros/Cigar.config.mac +++ b/macros/Cigar.config.mac @@ -18,4 +18,4 @@ ### JOB CONTROL /nexus/random_seed 1 /nexus/persistency/start_id 0 -/nexus/persistency/output_file Cigar.next +/nexus/persistency/output_file Cigar diff --git a/running_nexus.sh b/running_nexus.sh new file mode 100644 index 000000000..ce45ac7f3 --- /dev/null +++ b/running_nexus.sh @@ -0,0 +1,64 @@ +#!/bin/bash + +# Geant4 Path, edit G4Install path to where the main geant4 code folder your downloaded +export G4INSTALL=/home/investigator/Documents/simulation_software//geant4-v11.0.2/install; +export PATH=$G4INSTALL/bin:$PATH; +export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:$G4INSTALL/lib; +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$G4INSTALL/lib; + +echo geant4; + +cd $G4INSTALL/bin; +source geant4.sh; +cd -; + +echo g4finished; + +export QT_PATH=/home/investigator/Qt/5.15.2/gcc_64; +export PATH=$QT_PATH/bin:$PATH; +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$QT_PATH/lib; +export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:$QT_PATH/lib; + +echo QT; + +# Path to GSL +export GSL_PATH=/usr/local; +export PATH=$GSL_PATH/bin:$PATH; +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$GSL_PATH/lib; +export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:$GSL_PATH/lib; + +echo gsl; + +# Path to HDF5 +export HDF5_PATH=/usr/local/hdf5; # Set the installation path of HDF5 +export HDF5_LIB=/usr/local/hdf5/lib; # Set the path to HDF5 libraries +export HDF5_INC=/usr/local/hdf5/include; # Set the path to HDF5 headers + +echo hdf5; + +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HDF5_LIB; +export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:$HDF5_LIB; + +echo sourcing; + +# Source the default nexus setup file to set the nexusdir environmental variable +source /home/$USER/Documents/simulation_software/nexus_original/scripts/nexus_setup.sh; + +echo sourced; + +# Add the nexus exe to the path +export PATH=$PATH:/home/$USER/Documents/simulation_software/nexus_original/bin; + +#cmake compilation +cmake_compile () { +cmake --build build --target install +cd build; +cmake ..; +cmake --build . -j 32; +cd ..; +} + +echo "Setup Nexus is complete!" +echo "To compile run cmake_compile" + + diff --git a/source/geometries/Cigar.cc b/source/geometries/Cigar.cc index 82b98703a..c12994bb7 100644 --- a/source/geometries/Cigar.cc +++ b/source/geometries/Cigar.cc @@ -12,15 +12,19 @@ #include "OpticalMaterialProperties.h" #include "Visibilities.h" #include "GenericSquarePhotosensor.h" + #include #include #include +#include #include #include #include #include #include #include +#include + using namespace nexus; @@ -34,7 +38,7 @@ namespace nexus { cigar_width_ (30 * mm), fiber_diameter_(1 * mm), gas_("Ar"), - pressure_(1. * bar), + pressure_(0. * bar), coating_ ("TPB"), fiber_type_ ("Y11"), coated_(true) @@ -88,7 +92,10 @@ namespace nexus { G4cout << " with " << coating_ << " coating"; G4cout << G4endl; - inside_cigar_ = new BoxPointSampler(cigar_width_, cigar_width_, cigar_length_, 0, G4ThreeVector(0, 0, 0)); + G4RotationMatrix *temp_rot = new G4RotationMatrix(); + temp_rot->rotateY(0 * deg); + // inside_cigar_ = new BoxPointSampler(cigar_width_, cigar_width_, cigar_length_, 0, G4ThreeVector(0, 0, 0)); + inside_cigar_ = new BoxPointSampler(1*mm, 1*mm, 1*mm, 1*mm, G4ThreeVector(0.,0.,0.)); world_z_ = cigar_length_ * 2; world_xy_ = cigar_width_ * 2; @@ -104,6 +111,7 @@ namespace nexus { FatalException, "Invalid fiber type, must be Y11 or B2"); } + G4Material *this_coating = nullptr; G4MaterialPropertiesTable *this_coating_optical = nullptr; if (coated_) { @@ -119,7 +127,7 @@ namespace nexus { } } - fiber_ = new GenericWLSFiber(fiber_type_, true, true, fiber_diameter_, cigar_length_ + 7 * cm, true, coated_, this_fiber, this_coating, true); + fiber_ = new GenericWLSFiber(fiber_type_, true, true, fiber_diameter_, cigar_length_ + 7 * cm, true, coated_, this_coating, this_fiber, true); // WORLD ///////////////////////////////////////////////// @@ -128,9 +136,11 @@ namespace nexus { if (gas_ == "Ar") { world_mat = materials::GAr(pressure_); world_mat->SetMaterialPropertiesTable(opticalprops::GAr(1. / (68 * eV))); + } else if (gas_ == "Xe") { world_mat = materials::GXe(pressure_); - world_mat->SetMaterialPropertiesTable(opticalprops::GXe(pressure_)); + // world_mat->SetMaterialPropertiesTable(opticalprops::GXe(pressure_, 273.15, 250, (1.0E9))); + world_mat->SetMaterialPropertiesTable(opticalprops::GXe()); } else { G4Exception("[Cigar]", "Construct()", FatalException, "Invalid gas, must be Ar or Xe"); @@ -146,53 +156,65 @@ namespace nexus { // TEFLON PANELS //////////////////////////////////////////// G4double panel_width = 2.5 * mm; - G4Box* teflon_panel = - new G4Box("TEFLON_PANEL", cigar_width_ / 2, panel_width / 2, cigar_length_ / 2); - G4Box* teflon_panel_up = - new G4Box("TEFLON_PANEL", cigar_width_ / 2, cigar_width_ / 2, panel_width / 2); + G4double extra_width = (5) * mm; + // G4Box* teflon_panel_top = + // new G4Box("TEFLON_PANEL_TOP", cigar_width_ / 2 + extra_width + panel_width, panel_width / 2, cigar_length_ / 2); + G4Box* teflon_panel_top = + new G4Box("TEFLON_PANEL_TOP", cigar_width_ / 2 + extra_width + panel_width, panel_width / 2, cigar_length_ / 2); + G4Box* teflon_panel_side = + new G4Box("TEFLON_PANEL_SIDE", cigar_width_ / 2 + extra_width, panel_width / 2, cigar_length_ / 2); + G4Box* teflon_panel_close = + new G4Box("TEFLON_PANEL_CLOSE", cigar_width_ / 2 + extra_width+panel_width, cigar_width_ / 2 + extra_width+panel_width, panel_width / 2); G4Material* teflon = G4NistManager::Instance()->FindOrBuildMaterial("G4_TEFLON"); teflon->SetMaterialPropertiesTable(opticalprops::PTFE()); - G4LogicalVolume* teflon_logic = - new G4LogicalVolume(teflon_panel, teflon, "TEFLON"); - G4LogicalVolume* teflon_logic_up = - new G4LogicalVolume(teflon_panel_up, teflon, "TEFLON_UP"); - teflon_logic->SetVisAttributes(nexus::White()); - teflon_logic_up->SetVisAttributes(nexus::White()); + G4LogicalVolume* teflon_logic_top = + new G4LogicalVolume(teflon_panel_top, teflon, "TEFLON"); + G4LogicalVolume* teflon_logic_side = + new G4LogicalVolume(teflon_panel_side, teflon, "TEFLON"); + G4LogicalVolume* teflon_logic_close = + new G4LogicalVolume(teflon_panel_close, teflon, "TEFLON_CLOSE"); + teflon_logic_top->SetVisAttributes(nexus::White()); + teflon_logic_side->SetVisAttributes(nexus::White()); + teflon_logic_close->SetVisAttributes(nexus::White()); + + + + G4OpticalSurface* opsur_teflon = new G4OpticalSurface("TEFLON_OPSURF", unified, groundteflonair, dielectric_metal); opsur_teflon->SetMaterialPropertiesTable(opticalprops::PTFE()); - new G4LogicalSkinSurface("TEFLON_OPSURF", teflon_logic, opsur_teflon); + new G4LogicalSkinSurface("TEFLON_OPSURF", teflon_logic_top, opsur_teflon); - new G4PVPlacement(0, G4ThreeVector(0, cigar_width_/2+panel_width/2+fiber_diameter_, 0), - teflon_logic, "TEFLON1", world_logic_vol, + G4VPhysicalVolume *teflon_top = new G4PVPlacement(0, G4ThreeVector(0, cigar_width_/2+panel_width/2+fiber_diameter_+extra_width/2+panel_width/2+fiber_diameter_/4,0), + teflon_logic_top, "TEFLON1", world_logic_vol, true, 0, false); - new G4PVPlacement(0, G4ThreeVector(0, -cigar_width_/2-panel_width/2-fiber_diameter_, 0), - teflon_logic, "TEFLON2", world_logic_vol, + G4VPhysicalVolume *teflon_bottom = new G4PVPlacement(0, G4ThreeVector(0, -cigar_width_/2-panel_width/2-fiber_diameter_-(+extra_width/2+panel_width/2+fiber_diameter_/4), 0), + teflon_logic_top, "TEFLON2", world_logic_vol, true, 1, false); - new G4PVPlacement(0, G4ThreeVector(0, 0, cigar_length_/2+panel_width/2), - teflon_logic_up, "TEFLON3", world_logic_vol, - true, 1, false); + // new G4PVPlacement(0, G4ThreeVector(0, 0, cigar_length_/2+panel_width/2), + // teflon_logic_close, "TEFLON_FRONT", world_logic_vol, + // true, 1, false); new G4PVPlacement(0, G4ThreeVector(0, 0, -cigar_length_/2-panel_width/2), - teflon_logic_up, "TEFLON3", world_logic_vol, + teflon_logic_close, "TEFLON_BACK", world_logic_vol, true, 1, false); G4RotationMatrix *rot_x = new G4RotationMatrix(); rot_x->rotateZ(90 * deg); - new G4PVPlacement(G4Transform3D(*rot_x, G4ThreeVector(cigar_width_ / 2 + panel_width / 2 + fiber_diameter_, 0, 0)), - teflon_logic, "TEFLON3", world_logic_vol, + new G4PVPlacement(G4Transform3D(*rot_x, G4ThreeVector(cigar_width_ / 2 + panel_width / 2 + fiber_diameter_+extra_width/2+panel_width/2+fiber_diameter_/4, 0, 0)), + teflon_logic_side, "TEFLON3", world_logic_vol, true, 1, false); - new G4PVPlacement(G4Transform3D(*rot_x, G4ThreeVector(-cigar_width_ / 2 - panel_width / 2 - fiber_diameter_, 0, 0)), - teflon_logic, "TEFLON4", world_logic_vol, + new G4PVPlacement(G4Transform3D(*rot_x, G4ThreeVector(-cigar_width_ / 2 - panel_width / 2 - fiber_diameter_-extra_width/2-panel_width/2-fiber_diameter_/4, 0, 0)), + teflon_logic_side, "TEFLON4", world_logic_vol, true, 1, false); // // FIBER //////////////////////////////////////////////////// - + fiber_->SetCoreOpticalProperties(this_fiber_optical); fiber_->SetCoatingOpticalProperties(this_coating_optical); @@ -275,75 +297,213 @@ namespace nexus { // // PLACEMENT ///////////////////////////////////////////// G4RotationMatrix *rot_y = new G4RotationMatrix(); + G4RotationMatrix *rot_z = new G4RotationMatrix(); rot_y->rotateY(180 * deg); - new G4PVPlacement(G4Transform3D(*rot_y, G4ThreeVector(cigar_width_ / 2 + fiber_diameter_ / 2, 0, cigar_length_ / 2 + photosensor_thickness / 2 + 7 * cm)), + rot_z->rotateZ(90 * deg); + new G4PVPlacement(G4Transform3D(*rot_y, G4ThreeVector(cigar_width_ / 2 + fiber_diameter_ / 2+extra_width/2+panel_width/2+fiber_diameter_/4, 0, cigar_length_ / 2 + photosensor_thickness / 2 + 7 * cm)), sipm_logic, "SIPM1", world_logic_vol, false, 1, false); - new G4PVPlacement(G4Transform3D(*rot_y, G4ThreeVector(- cigar_width_ / 2 - fiber_diameter_ / 2, 0, cigar_length_ / 2 + photosensor_thickness / 2 + 7 * cm)), + new G4PVPlacement(G4Transform3D(*rot_y, G4ThreeVector(- cigar_width_ / 2 - fiber_diameter_ / 2-(extra_width/2+panel_width/2+fiber_diameter_/4), 0, cigar_length_ / 2 + photosensor_thickness / 2 + 7 * cm)), sipm_logic, "SIPM2", world_logic_vol, false, 2, false); - rot_y->rotateZ(90 * deg); - new G4PVPlacement(G4Transform3D(*rot_y, G4ThreeVector(0, - cigar_width_ / 2 - fiber_diameter_ / 2, cigar_length_ / 2 + photosensor_thickness / 2 + 7 * cm)), + new G4PVPlacement(G4Transform3D(*rot_z, G4ThreeVector(0, - cigar_width_ / 2 - fiber_diameter_ / 2-(extra_width/2+panel_width/2+fiber_diameter_/4), cigar_length_ / 2 + photosensor_thickness / 2 + 7 * cm)), sipm_logic, "SIPM3", world_logic_vol, false, 3, false); - new G4PVPlacement(G4Transform3D(*rot_y, G4ThreeVector(0, cigar_width_ / 2 + fiber_diameter_ / 2, cigar_length_ / 2 + photosensor_thickness / 2 + 7 * cm)), + new G4PVPlacement(G4Transform3D(*rot_z, G4ThreeVector(0, cigar_width_ / 2 + fiber_diameter_ / 2+extra_width/2+panel_width/2+fiber_diameter_/4, cigar_length_ / 2 + photosensor_thickness / 2 + 7 * cm)), sipm_logic, "SIPM4", world_logic_vol, false, 4, false); + + + + // Teflon special closing panel + G4Box* teflon_closing_panel = + new G4Box("TEFLON_PANEL_FRONT_TEMP", cigar_width_ / 2 + extra_width+panel_width, cigar_width_ / 2 + extra_width+panel_width, panel_width / 2); + // G4LogicalVolume* teflon_logic_front = + // new G4LogicalVolume(teflon_closing_panel, teflon, "TEFLON"); + // teflon_logic_front->SetVisAttributes(nexus::White()); + G4VSolid* temp_solid = teflon_closing_panel; + G4double fiber_radius = fiber_diameter_/1.1; + G4double fiber_length = fiber_->GetLength(); + G4VSolid* fiber_solid = new G4Tubs("FIBER_SOLID", 0, fiber_radius / 2, fiber_length / 2, 0, 2 * pi); + G4SubtractionSolid* subtracted_solid = nullptr; + + for (G4int ifiber = 0; ifiber < n_fibers; ifiber++) { std::string label = std::to_string(ifiber); - new G4PVPlacement(0, G4ThreeVector(cigar_width_ / 2 + fiber_diameter_ / 2, -cigar_width_ / 2 + ifiber * fiber_diameter_ + fiber_diameter_ / 2, 3.5 * cm), - fiber_logic, "FIBER1-" + label, world_logic_vol, - true, ifiber, false); + G4PVPlacement* fiber_placement1 = new G4PVPlacement(0, G4ThreeVector(cigar_width_ / 2 + fiber_diameter_ / 2+extra_width/2+panel_width/2+fiber_diameter_/4, -cigar_width_ / 2 + ifiber * fiber_diameter_ + fiber_diameter_ / 2, 3.5 * cm), + fiber_logic, "FIBER1-" + label, world_logic_vol, + true, ifiber, false); - new G4PVPlacement(0, G4ThreeVector(-cigar_width_ / 2 - fiber_diameter_ / 2, -cigar_width_ / 2 + ifiber * fiber_diameter_ + fiber_diameter_ / 2, 3.5 * cm), - fiber_logic, "FIBER2-" + label, world_logic_vol, - true, ifiber * 2, false); + G4PVPlacement* fiber_placement2 = new G4PVPlacement(0, G4ThreeVector(-cigar_width_ / 2 - fiber_diameter_ / 2-(extra_width/2+panel_width/2+fiber_diameter_/4), -cigar_width_ / 2 + ifiber * fiber_diameter_ + fiber_diameter_ / 2, 3.5 * cm), + fiber_logic, "FIBER2-" + label, world_logic_vol, + true, ifiber * 2, false); - new G4PVPlacement(0, G4ThreeVector(-cigar_width_ / 2 + ifiber * fiber_diameter_ + fiber_diameter_ / 2, -cigar_width_ / 2 - fiber_diameter_ / 2, 3.5 * cm), - fiber_logic, "FIBER3-" + label, world_logic_vol, - true, ifiber * 3, false); + G4PVPlacement* fiber_placement3 = new G4PVPlacement(0, G4ThreeVector(-cigar_width_ / 2 + ifiber * fiber_diameter_ + fiber_diameter_ / 2, -cigar_width_ / 2 - fiber_diameter_ / 2-(extra_width/2+panel_width/2+fiber_diameter_/4), 3.5 * cm), + fiber_logic, "FIBER3-" + label, world_logic_vol, + true, ifiber * 3, false); - new G4PVPlacement(0, G4ThreeVector(-cigar_width_ / 2 + ifiber * fiber_diameter_ + fiber_diameter_ / 2, cigar_width_ / 2 + fiber_diameter_ / 2, 3.5 * cm), - fiber_logic, "FIBER4-" + label, world_logic_vol, - true, ifiber * 4, false); + G4PVPlacement* fiber_placement4 = new G4PVPlacement(0, G4ThreeVector(-cigar_width_ / 2 + ifiber * fiber_diameter_ + fiber_diameter_ / 2, cigar_width_ / 2 + fiber_diameter_ / 2+(extra_width/2+panel_width/2+fiber_diameter_/4), 3.5 * cm), + fiber_logic, "FIBER4-" + label, world_logic_vol, + true, ifiber * 4, false); - new G4PVPlacement(0, G4ThreeVector(cigar_width_ / 2 + fiber_diameter_ / 2, -cigar_width_ / 2 + ifiber * fiber_diameter_ + fiber_diameter_ / 2, -cigar_length_ / 2 - fiber_end_z), + new G4PVPlacement(0, G4ThreeVector(cigar_width_ / 2 + fiber_diameter_ / 2+extra_width/2+panel_width/2+fiber_diameter_/4, -cigar_width_ / 2 + ifiber * fiber_diameter_ + fiber_diameter_ / 2, -cigar_length_ / 2 - fiber_end_z), fiber_end_logic_vol, "ALUMINUM1-" + label, world_logic_vol, true, ifiber, false); - new G4PVPlacement(0, G4ThreeVector(-cigar_width_ / 2 - fiber_diameter_ / 2, -cigar_width_ / 2 + ifiber * fiber_diameter_ + fiber_diameter_ / 2, -cigar_length_ / 2 - fiber_end_z), + new G4PVPlacement(0, G4ThreeVector(-cigar_width_ / 2 - fiber_diameter_ / 2-(extra_width/2+panel_width/2+fiber_diameter_/4), -cigar_width_ / 2 + ifiber * fiber_diameter_ + fiber_diameter_ / 2, -cigar_length_ / 2 - fiber_end_z), fiber_end_logic_vol, "ALUMINUM2-" + label, world_logic_vol, true, ifiber, false); - new G4PVPlacement(0, G4ThreeVector(-cigar_width_ / 2 + ifiber * fiber_diameter_ + fiber_diameter_ / 2, -cigar_width_ / 2 - fiber_diameter_ / 2, -cigar_length_ / 2 - fiber_end_z), + new G4PVPlacement(0, G4ThreeVector(-cigar_width_ / 2 + ifiber * fiber_diameter_ + fiber_diameter_ / 2, -cigar_width_ / 2 - fiber_diameter_ / 2-(extra_width/2+panel_width/2+fiber_diameter_/4), -cigar_length_ / 2 - fiber_end_z), fiber_end_logic_vol, "ALUMINUM3-" + label, world_logic_vol, true, ifiber, false); - new G4PVPlacement(0, G4ThreeVector(-cigar_width_ / 2 + ifiber * fiber_diameter_ + fiber_diameter_ / 2, cigar_width_ / 2 + fiber_diameter_ / 2, -cigar_length_ / 2 - fiber_end_z), + new G4PVPlacement(0, G4ThreeVector(-cigar_width_ / 2 + ifiber * fiber_diameter_ + fiber_diameter_ / 2, cigar_width_ / 2 + fiber_diameter_ / 2+(extra_width/2+panel_width/2+fiber_diameter_/4), -cigar_length_ / 2 - fiber_end_z), fiber_end_logic_vol, "ALUMINUM4-" + label, world_logic_vol, true, ifiber, false); + + + + + + // Create a cylinder solid to represent the fiber + + subtracted_solid = new G4SubtractionSolid("SUBTRACTED_SOLID", temp_solid, fiber_solid, rot_z, G4ThreeVector(cigar_width_ / 2 + fiber_diameter_ / 2+extra_width/2+panel_width/2+fiber_diameter_/4, -cigar_width_ / 2 + ifiber * fiber_diameter_ + fiber_diameter_ / 2, 3.5 * cm)); + temp_solid = subtracted_solid; + subtracted_solid = new G4SubtractionSolid("SUBTRACTED_SOLID", temp_solid, fiber_solid, rot_z, G4ThreeVector(-cigar_width_ / 2 - fiber_diameter_ / 2-(extra_width/2+panel_width/2+fiber_diameter_/4), -cigar_width_ / 2 + ifiber * fiber_diameter_ + fiber_diameter_ / 2, 3.5 * cm)); + temp_solid = subtracted_solid; + subtracted_solid = new G4SubtractionSolid("SUBTRACTED_SOLID", temp_solid, fiber_solid, 0, G4ThreeVector(-cigar_width_ / 2 + ifiber * fiber_diameter_ + fiber_diameter_ / 2, -cigar_width_ / 2 - fiber_diameter_ / 2-(extra_width/2+panel_width/2+fiber_diameter_/4), 3.5 * cm)); + temp_solid = subtracted_solid; + subtracted_solid = new G4SubtractionSolid("SUBTRACTED_SOLID", temp_solid, fiber_solid, 0, G4ThreeVector(-cigar_width_ / 2 + ifiber * fiber_diameter_ + fiber_diameter_ / 2, cigar_width_ / 2 + fiber_diameter_ / 2+(extra_width/2+panel_width/2+fiber_diameter_/4), 3.5 * cm)); + temp_solid = subtracted_solid; + + + } + + + // Simpler Teflon Close + + G4VSolid* teflon_closing_panel_temp = + new G4Box("TEFLON_PANEL_FRONT_TEMP", cigar_width_ / 2 + extra_width+panel_width, cigar_width_ / 2 + extra_width+panel_width, panel_width / 2); + G4VSolid* fiber_space = + new G4Box("TEFLON_PANEL_FRONT_TEMP", fiber_diameter_, cigar_width_ / 2, panel_width / 2); + G4SubtractionSolid* subtracted_solid_test = new G4SubtractionSolid("SUBTRACTED_SOLID", teflon_closing_panel_temp, fiber_space, rot_z, G4ThreeVector(0,cigar_width_ / 2 + fiber_diameter_ / 2+extra_width/2+panel_width/2+fiber_diameter_/4,0)); + subtracted_solid_test = new G4SubtractionSolid("SUBTRACTED_SOLID", subtracted_solid_test, fiber_space, rot_z, G4ThreeVector(0,-cigar_width_ / 2 - fiber_diameter_ / 2-(extra_width/2+panel_width/2+fiber_diameter_/4),0)); + rot_y->rotateY(90 * deg); + subtracted_solid_test = new G4SubtractionSolid("SUBTRACTED_SOLID", subtracted_solid_test, fiber_space, rot_y, G4ThreeVector(-cigar_width_ / 2 - fiber_diameter_ / 2-(extra_width/2+panel_width/2+fiber_diameter_/4),0,0)); + subtracted_solid_test = new G4SubtractionSolid("SUBTRACTED_SOLID", subtracted_solid_test, fiber_space, rot_y, G4ThreeVector(+cigar_width_ / 2 + fiber_diameter_ / 2+(extra_width/2+panel_width/2+fiber_diameter_/4),0,0)); + + G4LogicalVolume* teflon_closing_panel_logic_temp = new G4LogicalVolume(subtracted_solid_test, teflon, "TEFLON_PANEL"); + teflon_closing_panel_logic_temp->SetVisAttributes(nexus::White()); + rot_x->rotateZ(90 * deg); + new G4PVPlacement(rot_x, G4ThreeVector(0, 0, cigar_length_/2+panel_width/2), teflon_closing_panel_logic_temp, "TEFLON_FRONT", world_logic_vol, true, 1, false); + + + // Create logical volume for the modified box after subtracting fibers + // G4LogicalVolume* teflon_closing_panel_logic = new G4LogicalVolume(temp_solid, teflon, "TEFLON_PANEL"); + // teflon_closing_panel_logic->SetVisAttributes(nexus::White()); + // rot_x->rotateZ(90 * deg); + // new G4PVPlacement(rot_x, G4ThreeVector(0, 0, cigar_length_/2+panel_width/2), teflon_closing_panel_logic, "TEFLON_FRONT", world_logic_vol, true, 1, false); + + + + + + + + // // Vacuum chamber + + // G4Tubs* vacuum_chamber = + // new G4Tubs("VACUUM_CHAMBER", cigar_width_+3*cm, cigar_width_+5*cm, cigar_length_, 0,2*pi); + // G4Material* steel = materials::Steel(); + + // G4LogicalVolume* vacuum_chamber_logic = + // new G4LogicalVolume(vacuum_chamber, steel, "CHAMBER"); + + + // vacuum_chamber_logic->SetVisAttributes(nexus::DarkGrey()); + + // new G4PVPlacement(0, G4ThreeVector(0, 0, 0), + // vacuum_chamber_logic, "VAC_CHAMBER", world_logic_vol, + // true, 0, false); + + + + + + // G4OpticalSurface* opsur_teflon = + // new G4OpticalSurface("TEFLON_OPSURF", unified, groundteflonair, dielectric_metal); + // opsur_teflon->SetMaterialPropertiesTable(opticalprops::PTFE()); + + // new G4LogicalSkinSurface("TEFLON_OPSURF", teflon_logic_top, opsur_teflon); + + // new G4PVPlacement(0, G4ThreeVector(0, 0, cigar_length_/2+panel_width/2), + // teflon_logic_close, "TEFLON_FRONT", world_logic_vol, + // true, 1, false); + + + // // Check source position inside CIGAR + + // G4Material * cylinder_material = materials::OpticalSilicone(); + // cylinder_material->SetMaterialPropertiesTable(opticalprops::PTFE()); + + // G4Tubs* LED_cylinder = new G4Tubs("CYLINDER", 10*mm, 15*mm, 20*mm, 0, 2*pi ); + // G4LogicalVolume* LED_logic = + // new G4LogicalVolume(LED_cylinder, + // cylinder_material, + // "CYLINDER"); + // LED_logic->SetVisAttributes(nexus::BloodRed()); + // new G4PVPlacement(0, G4ThreeVector(0, 0, 0), + // LED_logic, "CYLINDER", world_logic_vol, + // true, 1, true); + + + + // G4OpticalSurface* ptfe_surface = new G4OpticalSurface("PTFE_SURFACE"); + // ptfe_surface->SetType(dielectric_LUT); + // ptfe_surface->SetFinish(polishedteflonair); + // ptfe_surface->SetModel(LUT); + // ptfe_surface->SetMaterialPropertiesTable(opticalprops::PTFE()); + + // new G4LogicalBorderSurface( + // "XE_PTFE", world_logic_vol, teflon_top, ptfe_surface); } + // G4ThreeVector Cigar::GenerateVertex(const G4String& region) const + // { + // G4ThreeVector vertex(0., 0., 0.); + + // // WORLD + // if (region == "INSIDE_CIGAR") { + // // return vertex; + // return inside_cigar_->GenerateVertex(nexus::INSIDE); + // // return inside_cigar_->GenerateVertex(nexus::VOLUME); + // } else { + // G4Exception("[Cigar]", "GenerateVertex()", FatalException, + // "Unknown vertex generation region!"); + // } + // return vertex; + // } G4ThreeVector Cigar::GenerateVertex(const G4String& region) const { - G4ThreeVector vertex(0.,0.,0.); + G4ThreeVector vertex(0., 0., 0.); // WORLD if (region == "INSIDE_CIGAR") { // return vertex; return inside_cigar_->GenerateVertex("INSIDE"); - } - else { + // return inside_cigar_->GenerateVertex(nexus::VOLUME); + } else { G4Exception("[Cigar]", "GenerateVertex()", FatalException, - "Unknown vertex generation region!"); + "Unknown vertex generation region!"); } return vertex; } diff --git a/source/geometries/Cigar.h b/source/geometries/Cigar.h index 9d7cdb322..59b60b346 100644 --- a/source/geometries/Cigar.h +++ b/source/geometries/Cigar.h @@ -6,8 +6,8 @@ // The NEXT Collaboration // ---------------------------------------------------------------------------- -#ifndef Cigar_H -#define Cigar_H +#ifndef CIGAR_H +#define CIGAR_H #include "GeometryBase.h" #include "GenericWLSFiber.h"