Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-23 09:20:36

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 //
0027 /// \file XrayTESdetDetectorConstruction.cc
0028 /// \brief Implementation of the XrayTESdetDetectorConstruction class
0029 //
0030 // Authors: P.Dondero (paolo.dondero@cern.ch), R.Stanzani (ronny.stanzani@cern.ch)
0031 //
0032 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0033 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0034 
0035 
0036 #include "XrayTESdetDetectorConstruction.hh"
0037 #include "XrayTESdetDetectorMessenger.hh"
0038 #include "XrayTESdetDetParameterisation.hh"
0039 #include "G4Material.hh"
0040 #include "G4Sphere.hh"
0041 #include "G4Box.hh"
0042 #include "G4Tubs.hh"
0043 #include "G4LogicalVolume.hh"
0044 #include "G4ThreeVector.hh"
0045 #include "G4PVPlacement.hh"
0046 #include "G4PVParameterised.hh"
0047 #include "globals.hh"
0048 #include "G4SDManager.hh"
0049 #include "G4GeometryTolerance.hh"
0050 #include "G4GeometryManager.hh"
0051 #include "G4UserLimits.hh"
0052 #include "G4VisAttributes.hh"
0053 #include "G4Colour.hh"
0054 #include "G4ios.hh"
0055 #include "G4SubtractionSolid.hh"
0056 #include "G4Cons.hh"
0057 #include "G4RotationMatrix.hh"
0058 #include "G4PVReplica.hh"
0059 #include "G4NistManager.hh"
0060 #include "G4Cons.hh"
0061 #include "G4Polyhedra.hh"
0062 #include "G4PVParameterised.hh"
0063 #include "G4Trap.hh"
0064 #include "G4Trd.hh"
0065 #include "G4Hype.hh"
0066 #include "G4ExtrudedSolid.hh"
0067 #include "G4SystemOfUnits.hh"
0068 #include "G4PhysicalConstants.hh"
0069 
0070 // #include <stdio.h>
0071 #include <cmath>
0072 #include <iostream>
0073 #include <fstream>
0074 #include <iomanip>
0075 #include <string>
0076 #include <vector>
0077 #include <algorithm>
0078 #include <sstream>
0079 
0080 #include "G4GDMLParser.hh"
0081 #include "G4PhysicalVolumeStore.hh"
0082 #include "G4ProductionCuts.hh"
0083 #include "G4ProductionCutsTable.hh"
0084 
0085 
0086 XrayTESdetDetectorConstruction::XrayTESdetDetectorConstruction()
0087 : fStepLimitPolyfilta(nullptr),fStepLimitAlfilta(nullptr),fStepLimitmembrane(nullptr),fExperimentalHall_phys(nullptr),fDetectorMessenger(nullptr)
0088 {
0089   fReadFile = "";
0090   fDetectorMessenger = new XrayTESdetDetectorMessenger(this);
0091 }
0092 
0093 
0094 XrayTESdetDetectorConstruction::~XrayTESdetDetectorConstruction()
0095 {
0096   delete fStepLimitAlfilta;
0097   delete fStepLimitPolyfilta;
0098   delete fStepLimitmembrane;
0099   delete fDetectorMessenger;
0100 }
0101 
0102 
0103 G4VPhysicalVolume* XrayTESdetDetectorConstruction::Construct()
0104 {
0105   return ConstructDetector();
0106 }
0107 
0108 
0109 G4VPhysicalVolume* XrayTESdetDetectorConstruction::ConstructDetector()
0110 {
0111   G4VPhysicalVolume* fWorld_phys;
0112   auto *InnerRegion = new G4Region("InnerRegion");
0113 
0114   if (fReadFile == "")
0115   {
0116     G4cout << "Build a new geometry" << G4endl;
0117 
0118     // -------------------------------------------------------------------------------------------
0119     // --------------- Define materials ----------------------------------------------------------
0120     // -------------------------------------------------------------------------------------------
0121     G4String symbol;
0122     G4int ncomponents;
0123     G4double density;
0124     G4double fractionmass;
0125 
0126     auto *man = G4NistManager::Instance();
0127     auto *Si = man->FindOrBuildMaterial("G4_Si");
0128     auto *Cu = man->FindOrBuildMaterial("G4_Cu");
0129     auto *Bi = man->FindOrBuildMaterial("G4_Bi");
0130     auto *Al = man->FindOrBuildMaterial("G4_Al");
0131     auto *Ni = man->FindOrBuildMaterial("G4_Ni");
0132     auto *Au = man->FindOrBuildMaterial("G4_Au");
0133     auto *N = man->FindOrBuildMaterial("G4_N");
0134     auto *Fe = man->FindOrBuildMaterial("G4_Fe");
0135     auto *C = man->FindOrBuildMaterial("G4_C");
0136     auto *Mn = man->FindOrBuildMaterial("G4_Mn");
0137     auto *Ph = man->FindOrBuildMaterial("G4_P");
0138     auto *S = man->FindOrBuildMaterial("G4_S");
0139     auto *Cr = man->FindOrBuildMaterial("G4_Cr");
0140     auto *Mo = man->FindOrBuildMaterial("G4_Mo");
0141     auto *Ti = man->FindOrBuildMaterial("G4_Ti");
0142 
0143     // Define the material of the ring
0144     auto *RingAl = new G4Material("RingAl", density=0.736*g/cm3, ncomponents=1);
0145     RingAl->AddMaterial(Al, fractionmass=1);
0146 
0147     // Define cryoperm
0148     auto *Cryoperm = new G4Material("Cryoperm", density=8.7*g/cm3, ncomponents=4);
0149     Cryoperm->AddMaterial(Ni, fractionmass=0.775);
0150     Cryoperm->AddMaterial(Cu, fractionmass=0.045);
0151     Cryoperm->AddMaterial(Mo, fractionmass=0.025);
0152     Cryoperm->AddMaterial(Fe, fractionmass=0.155);
0153 
0154     // Define vacuum
0155     auto *vacuum = man->FindOrBuildMaterial("G4_Galactic");
0156 
0157     // Define the Stainless Steel
0158     G4double SS_density = 8.03*g/cm3;
0159     auto *SS = new G4Material("Stainless Steel",density=SS_density,ncomponents=8);
0160     SS->AddMaterial(N, fractionmass=0.01);
0161     SS->AddMaterial(Ni, fractionmass=0.1);
0162     SS->AddMaterial(Cr, fractionmass=0.185);
0163     SS->AddMaterial(S, fractionmass=0.03);
0164     SS->AddMaterial(Ph, fractionmass=0.045);
0165     SS->AddMaterial(Mn, fractionmass=0.02);
0166     SS->AddMaterial(C, fractionmass=0.08);
0167     SS->AddMaterial(Fe, fractionmass=0.53);
0168 
0169     // Si3N4
0170     G4double A;
0171     G4double Z;
0172     auto *elSi = new G4Element("Silicon", "Si", Z=14., A=28.0855*g/mole);
0173     auto *elN = new G4Element("Nitrogen","N", Z=7., A=14.00674*g/mole);
0174     G4double Si3N4density = 3.44*g/cm3;
0175     auto *Si3N4 = new G4Material("Si3N4", Si3N4density, 2);
0176     Si3N4->AddElement (elSi, 3);
0177     Si3N4->AddElement (elN, 4);
0178 
0179     // -------------------------------------------------------------------------------------------
0180     // ----------------------------------- Define World volume -----------------------------------
0181     G4double expHall_x = 3*m;
0182     G4double expHall_y = 3*m;
0183     G4double expHall_z = 3*m;
0184 
0185     auto *experimentalHall_box = new G4Box("experimentalHall_box",expHall_x,expHall_y,expHall_z);
0186     fExperimentalHall_log = new G4LogicalVolume(experimentalHall_box,vacuum,"experimentalHall_log",0,0,0);// vacuum ok, its the mother volume
0187     fExperimentalHall_phys = new G4PVPlacement(nullptr,G4ThreeVector(), fExperimentalHall_log,"expHall",0,false,0);
0188 
0189     // -------------------------------------------------------------------------------------------
0190     // ------------------------------------ Define TES array -------------------------------------
0191     //absorber: 3 µm Bi
0192     G4double Biabsorberthickness = 3*um;
0193     G4double Gridthickness = 200*um;
0194     G4double membrane_thickness = 0.75*um;
0195     G4double wafer_thickness = 0.25*mm;
0196 
0197     //height of the entire volume to be replicated
0198     G4double xifu_z = Biabsorberthickness+Gridthickness+membrane_thickness;
0199 
0200     //size of the mother volume to be replicated
0201     G4double pxl_pitch = 0.814*mm;//V2 res90
0202     G4double pxl_gap = 11*um;
0203     G4double pxl_size = pxl_pitch-pxl_gap;
0204     G4double grid_size = pxl_pitch;
0205 
0206     G4double DetPos_x = 0.0*mm;
0207     G4double DetPos_y = 0.0*mm;
0208     G4double DetPos_z = -xifu_z; //So that the absorbers surface is at z=0
0209 
0210     //mother volume of the detector has hexagonal shape
0211     G4double phiStart = 0;
0212     G4double phiTotal = 0;
0213     G4int numSide = 6;
0214     G4int numZPlanes = 2;
0215     G4double rInner[2] = {0,0};
0216 
0217     //end of parameters definitions
0218     auto *element_box = new G4Box("element_box",grid_size*0.5,grid_size*0.5,xifu_z*0.5);
0219     fElement_log = new G4LogicalVolume(element_box,vacuum,"element_log");
0220 
0221     //definition of the mother volume containing the replicated elements
0222     G4String pName = "Detector_hex";
0223     G4double zPlane[2] = {-xifu_z*0.5,xifu_z*0.5};
0224 
0225     G4double rOuter[2] = {8.5*mm,8.5*mm};//apothem
0226 
0227     G4Polyhedra* Detector_hex = new G4Polyhedra(pName,
0228     phiStart,
0229     phiTotal,
0230     numSide,
0231     numZPlanes,
0232     zPlane,
0233     rInner,
0234     rOuter);
0235 
0236     fDetector_log = new G4LogicalVolume(Detector_hex,vacuum,"Detector_log");//vacuum ok, it's the mother volume
0237     fDetector_phys = new G4PVPlacement(nullptr, G4ThreeVector(DetPos_x,DetPos_y,DetPos_z+0.0001*um),fDetector_log,"Detector",fExperimentalHall_log, false, 0);
0238 
0239     //Bi absorber 3 um
0240     auto *Bipxl_box = new G4Box("Bipxl_box",pxl_size*0.5,pxl_size*0.5,Biabsorberthickness*0.5);
0241     fBipxl_log = new G4LogicalVolume(Bipxl_box,Bi,"Bipxl_log");
0242     fBipxl_phys = new G4PVPlacement(nullptr,G4ThreeVector(0., 0., xifu_z*0.5-Biabsorberthickness*0.5), fBipxl_log, "Bipxl", fElement_log, false, 0);
0243 
0244     //SiN membrane sustaing the absorbers
0245     auto *membranepxl_box = new G4Box("membranepxl_box",pxl_size*0.5,pxl_size*0.5,membrane_thickness*0.5);
0246     fMembranepxl_log = new G4LogicalVolume(membranepxl_box,Si3N4,"membranepxl_log");
0247     fMembranepxl_phys = new G4PVPlacement(nullptr,G4ThreeVector(0., 0., xifu_z*0.5-Biabsorberthickness-membrane_thickness*0.5), fMembranepxl_log, "membrane", fElement_log, false, 0);
0248 
0249     //step limiter: the membrane is really thin, thinner than the typical interaction step. This forces the particles to perform at least 5 interactions inside
0250     G4double maxStepmembrane = 0.2*membrane_thickness;
0251     fStepLimitmembrane = new G4UserLimits(maxStepmembrane);
0252     fMembranepxl_log->SetUserLimits(fStepLimitmembrane);
0253 
0254     // Grid element
0255     auto *gridbox = new G4Box("grid_box",grid_size*0.5,grid_size*0.5,Gridthickness*0.5);
0256     G4double gridbeam_size = 165*um;
0257     G4double gridhole_size = grid_size-gridbeam_size;
0258     G4double gridhole_thickness = Gridthickness+1*mm;
0259     auto *gridhole_box = new G4Box("gridhole_box",gridhole_size*0.5,gridhole_size*0.5,gridhole_thickness*0.5);
0260     G4SubtractionSolid* gridsubtraction = new G4SubtractionSolid("gridsubtraction",gridbox, gridhole_box);
0261     fGridpiece_log = new G4LogicalVolume(gridsubtraction,Si,"gridpiece_log");
0262     fGridpiece_phys = new G4PVPlacement(nullptr,G4ThreeVector(0., 0., xifu_z*0.5-Biabsorberthickness-membrane_thickness-Gridthickness*0.5), fGridpiece_log, "gridpiece", fElement_log, false, 0);
0263 
0264     //parametrization of element_log
0265     auto *DetParam = new XrayTESdetDetParameterisation(
0266                 317,//V1 and V2 res80 and res90 // to be commented for overlap check
0267                 //2,  // To enable volumes overlap check the number of replicas must be reduced. Keep it commented if not needed
0268                 -grid_size*38,
0269                 grid_size,
0270                 grid_size*0.5,
0271                 grid_size );
0272 
0273     fPhysiDet = new G4PVParameterised(
0274                   "Det",             // their name
0275                   fElement_log,       // their logical volume
0276                   fDetector_log,      // Mother logical volume
0277                   kXAxis,            // Are placed along this axis
0278                   317,               //V1 and V2 res80 and res90
0279                   //2,               // overlap check. Same as before.
0280                   DetParam);         // The parametrisation
0281 
0282     // ------------ Define support wafer ----------------------------------------------
0283     G4double rOutersupp[2] = {39.4*mm,39.4*0.5*mm};
0284     G4double zwaferPlane[2] = {-0.5*wafer_thickness,0.5*wafer_thickness};
0285 
0286     auto *wafer_hex = new G4Polyhedra("wafer_hex",
0287     phiStart,
0288     phiTotal,
0289     numSide,
0290     numZPlanes,
0291     zwaferPlane,
0292     rOuter,
0293     rOutersupp);
0294 
0295     fWafer_log = new G4LogicalVolume(wafer_hex,Si,"wafer_log");
0296     G4double wafer_z = -xifu_z*0.5-Biabsorberthickness-Gridthickness*0.5;
0297     fWafer_phys = new G4PVPlacement(nullptr, G4ThreeVector(DetPos_x,DetPos_y,wafer_z), fWafer_log,"wafer",fExperimentalHall_log, false, 0);
0298 
0299     //------------------------------------------------------------------------------------------------------
0300     //----------------------------------   BSC electron detector     ---------------------------------------
0301     // This fake surface placed just above the absorbers gathers information on the electrons crossing it
0302     // it can be used to check if the same particle crossed it twice, to identify backscattering events
0303     //------------------------------------------------------------------------------------------------------
0304     G4double BSC_z = 0.05*mm;  // half thickness
0305 
0306     G4String pBSCName = "BSCdetector";
0307     G4double zPlaneBSC[2] = {-BSC_z,BSC_z};
0308     G4double rOuterBSC[2] = {rOuter[0]+2*mm,rOuter[1]+2*mm};
0309 
0310     auto *BSC_hex = new G4Polyhedra(pBSCName,
0311       phiStart,
0312       phiTotal,
0313       numSide,
0314       numZPlanes,
0315       zPlaneBSC,
0316       rInner,
0317       rOuterBSC);
0318 
0319     fBSC_log = new G4LogicalVolume(BSC_hex,vacuum,"BSC_log");
0320 
0321     G4double BSCPos_x = 0.0*mm;
0322     G4double BSCPos_y = 0.0*mm;
0323     G4double BSCPos_z = wafer_z + wafer_thickness+BSC_z*0.5;
0324 
0325     fBSC_phys = new G4PVPlacement(nullptr, G4ThreeVector(BSCPos_x,BSCPos_y,BSCPos_z),fBSC_log,"BSC",fExperimentalHall_log, false, 0);
0326 
0327     // --------------------------------------------------------------------------------------------------------------------------------------------
0328     // -------------------------------------------------------- Define ACD inner array ------------------------------------------------------------
0329     // Anti Coincidence Detectors are usually thicker than the main ones. It can generate a huge output file if low cuts are used
0330     // defining a inner part of the ACD and assigning it to a lower precision region, thus allowing only the creation of high energy secondaries
0331     // can help speeding up the simulation and reducing the output size. In this example only the external 25 um belong to the higher precision region
0332     // --------------------------------------------------------------------------------------------------------------------------------------------
0333     G4double ACDthickness = 200*um;
0334     G4double ACD_distance = 0.75*mm; // distance from the lower edge of the main detector
0335     G4double ACDarrayPos_z = -1*(ACD_distance+Biabsorberthickness/2+ACDthickness/2);
0336     G4double ACDpxlGAP = 50*um;
0337 
0338     G4double pxlheight = 8.5*mm;
0339     G4double pxlwideside = pxlheight*1.191*mm;
0340     G4double pxlshortside = pxlwideside*0.5;
0341 
0342     G4double inACDthickness = ACDthickness-50*um;
0343 
0344     G4double inpxlheight = pxlheight-50*um;
0345     G4double inpxlwideside = pxlwideside-50*um;
0346     G4double inpxlshortside = inpxlwideside*0.5;
0347 
0348     auto *inACDpxl = new G4Trap("inACDpxl",
0349       inACDthickness,
0350       inpxlheight,
0351       inpxlwideside,
0352       inpxlshortside);
0353 
0354     fInACDpxl_log = new G4LogicalVolume(inACDpxl,Si,"inACDpxl_log");
0355     G4RotationMatrix rotm = G4RotationMatrix();
0356 
0357     //pxl1
0358     G4double ACDarrayPos1_x = (pxlshortside*1.5+ACDpxlGAP)*0.5;
0359     G4double ACDarrayPos1_y = (pxlheight+ACDpxlGAP)*0.5;
0360     fInACDpxl_phys = new G4PVPlacement(nullptr, G4ThreeVector(ACDarrayPos1_x,ACDarrayPos1_y,ACDarrayPos_z),fInACDpxl_log,"pxl1",fExperimentalHall_log, false, 0);
0361 
0362     //pxl2
0363     rotm.rotateZ(180*deg);
0364     G4double ACDarrayPos2_x = -ACDarrayPos1_x;
0365     G4double ACDarrayPos2_y = -ACDarrayPos1_y;
0366     G4ThreeVector position2 = G4ThreeVector(ACDarrayPos2_x,ACDarrayPos2_y,ACDarrayPos_z);
0367     G4Transform3D transform2 = G4Transform3D(rotm,position2);
0368     fInACDpxl_phys = new G4PVPlacement(transform2,fInACDpxl_log,"pxl2",fExperimentalHall_log, false, 0);
0369 
0370     //pxl3
0371     rotm.rotateY(180*deg);
0372     G4double ACDarrayPos3_x = ACDarrayPos1_x;
0373     G4double ACDarrayPos3_y = -ACDarrayPos1_y;
0374     G4ThreeVector position3 = G4ThreeVector(ACDarrayPos3_x,ACDarrayPos3_y,ACDarrayPos_z);
0375     G4Transform3D transform3 = G4Transform3D(rotm,position3);
0376     fInACDpxl_phys = new G4PVPlacement(transform3,fInACDpxl_log,"pxl3",fExperimentalHall_log, false, 0);
0377 
0378     //pxl4
0379     rotm.rotateZ(180*deg);
0380     G4double ACDarrayPos4_x = -ACDarrayPos1_x;
0381     G4double ACDarrayPos4_y = ACDarrayPos1_y;
0382     G4ThreeVector position4 = G4ThreeVector(ACDarrayPos4_x,ACDarrayPos4_y,ACDarrayPos_z);
0383     G4Transform3D transform4 = G4Transform3D(rotm,position4);
0384     fInACDpxl_phys = new G4PVPlacement(transform4,fInACDpxl_log,"pxl4",fExperimentalHall_log, false, 0);
0385 
0386     // ----------------------------------------------------------------------------------
0387     // -------------------- Define ACD outer layer array --------------------------------
0388     auto *ACDpxl = new G4Trap("ACDpxl",
0389       ACDthickness,
0390       pxlheight,
0391       pxlwideside,
0392       pxlshortside);
0393     G4SubtractionSolid* ACDsub = new G4SubtractionSolid("ACDsub",ACDpxl, inACDpxl);
0394     fACDpxl_log = new G4LogicalVolume(ACDsub,Si,"ACDpxl_log");
0395 
0396     //pxl1
0397     fACDpxl_phys = new G4PVPlacement(nullptr, G4ThreeVector(ACDarrayPos1_x,ACDarrayPos1_y,ACDarrayPos_z),fACDpxl_log,"pxl1a",fExperimentalHall_log, false, 0);
0398 
0399     //pxl2
0400     fACDpxl_phys = new G4PVPlacement(transform2,fACDpxl_log,"pxl2a",fExperimentalHall_log, false, 0);
0401 
0402     //pxl3
0403     fACDpxl_phys = new G4PVPlacement(transform3,fACDpxl_log,"pxl3a",fExperimentalHall_log, false, 0);
0404 
0405     //pxl4
0406     fACDpxl_phys = new G4PVPlacement(transform4,fACDpxl_log,"pxl4a",fExperimentalHall_log, false, 0);
0407 
0408     //------------------------------------------------------------------------------------------------------
0409     //-----------------------------------------SUPPORTS------------------------------------------------//
0410 
0411     //---------------------   ACD plate     --------------
0412     G4double ACplate_thickness = 3.5*mm;  // support thickness
0413 
0414     G4String ACplateName = "ACplateName";
0415     G4double ACplatezPlane[2] = {-0.5*ACplate_thickness,0.5*ACplate_thickness};
0416     G4double ACplaterInner[2] = {pxlwideside,pxlwideside};//apothem
0417     G4double ACplaterOuter[2] = {43*mm,43*mm};
0418 
0419     auto *ACplate_hex = new G4Polyhedra(ACplateName,
0420     phiStart,
0421     phiTotal,
0422     numSide,
0423     numZPlanes,
0424     ACplatezPlane,
0425     ACplaterInner,
0426     ACplaterOuter );
0427 
0428     fACplate_log = new G4LogicalVolume(ACplate_hex,Cu,"ACplate_log");//tbc
0429 
0430     G4double ACplatePos_x = DetPos_x;
0431     G4double ACplatePos_y = DetPos_y;
0432     G4double ACplatePos_z = -2.25*mm;
0433 
0434     fACplate_phys = new G4PVPlacement(nullptr, G4ThreeVector(ACplatePos_x,ACplatePos_y,ACplatePos_z),fACplate_log,"ACDplate",fExperimentalHall_log, false, 0);
0435 
0436     //------------------------------------------------------------------------------------------------------
0437     //----------------------------------------------   cage   ----------------------------------------------
0438     // ALL THE FOLLOWING SUPPORTING STRUCTURES DEFINE A COMPLEX SHAPE THAT WAS SIMPLIFIED AND ADAPTED FROM AN ENGINEERING CAD MODEL
0439     // ALL THE NUMBERS RELATIVE TO SIZES AND POSITIONS HAVE BEEN EXTRACTED FROM THE CAD FILE, THAT IS WHY THE NUMBERS ARE SO ODD
0440     // THIS IS MEANT JUST TO GIVE AN EXAMPLE OF THE SUPPORTING STRUCTURES PRESENT IN AN ACTUAL CRYOSTAT
0441 
0442     //------------------supporting columns (full)
0443     G4double hightOfcagecolumn = 60*mm;
0444 
0445     auto *cagecolumn = new G4Tubs("cagecolumn", 0*mm, 3.99*mm, hightOfcagecolumn*0.5, 0*deg, 360*deg);
0446     G4LogicalVolume* cagecolumn_log = new G4LogicalVolume(cagecolumn,Cu,"cagecolumn_log",0,0,0);
0447 
0448     fCagecolumn_phys = new G4PVPlacement(
0449       0,                                                      // no rotation
0450       G4ThreeVector(45.75*mm,0*mm,-36.5027*mm), // translation position
0451       cagecolumn_log,                                     // its logical volume
0452       "cagecolumn1",                             // its name
0453       fExperimentalHall_log,                                // its mother (logical) volume
0454       false,                                                  // no boolean operations
0455       0);
0456 
0457     fCagecolumn2_phys = new G4PVPlacement(
0458       0,
0459       G4ThreeVector(-45.75*mm,0*mm,-36.5027*mm),
0460       cagecolumn_log,
0461       "cagecolumn2",
0462       fExperimentalHall_log,
0463       false,
0464       0);
0465 
0466     fCagecolumn3_phys = new G4PVPlacement(
0467       0,
0468       G4ThreeVector(22.875*mm,39.621*mm,-36.5027*mm),
0469       cagecolumn_log,
0470       "cagecolumn3",
0471       fExperimentalHall_log,
0472       false,
0473       0);
0474 
0475     fCagecolumn4_phys = new G4PVPlacement(
0476       0,
0477       G4ThreeVector(22.875*mm,-39.621*mm,-36.5027*mm),
0478       cagecolumn_log,
0479       "cagecolumn4",
0480       fExperimentalHall_log,
0481       false,
0482       0);
0483 
0484     fCagecolumn5_phys = new G4PVPlacement(
0485       0,
0486       G4ThreeVector(-22.875*mm,-39.621*mm,-36.5027*mm),
0487       cagecolumn_log,
0488       "cagecolumn5",
0489       fExperimentalHall_log,
0490       false,
0491       0);
0492 
0493     fCagecolumn6_phys = new G4PVPlacement(
0494       0,
0495       G4ThreeVector(-22.875*mm,39.621*mm,-36.5027*mm),
0496       cagecolumn_log,
0497       "cagecolumn6",
0498       fExperimentalHall_log,
0499       false,
0500       0);
0501 
0502     //----------------------------------supporting columns (empty)
0503     auto *emptycagecolumn = new G4Tubs("emptycagecolumn", 1.25*mm, 3*mm, hightOfcagecolumn*0.5, 0*deg, 360*deg);
0504     G4LogicalVolume* emptycagecolumn_log = new G4LogicalVolume(emptycagecolumn,Cu,"emptycagecolumn_log",0,0,0);
0505 
0506     fEmptycagecolumn_phys = new G4PVPlacement(
0507       0,
0508       G4ThreeVector(22.875*mm,0*mm,-36.5027*mm),
0509       emptycagecolumn_log,
0510       "emptycagecolumn1",
0511       fExperimentalHall_log,
0512       false,
0513       0);
0514 
0515     fEmptycagecolumn2_phys = new G4PVPlacement(
0516       0,
0517       G4ThreeVector(-11.4375*mm,-19.8103311*mm,-36.5027*mm),
0518       emptycagecolumn_log,
0519       "emptycagecolumn2",
0520       fExperimentalHall_log,
0521       false,
0522       0);
0523 
0524     fEmptycagecolumn3_phys = new G4PVPlacement(
0525       0,
0526       G4ThreeVector(-11.4375*mm,19.810331*mm,-36.5027*mm),
0527       emptycagecolumn_log,
0528       "emptycagecolumn3",
0529       fExperimentalHall_log,
0530       false,
0531       0);
0532 
0533     //-----------------------walls
0534     G4double cagewall_x = 1*mm;
0535     G4double cagewall_y = 32.62*mm;
0536     G4double cagewall_z = 65*mm;
0537 
0538     auto *cagewall_box = new G4Box("_box",cagewall_x*0.5,cagewall_y*0.5,cagewall_z*0.5);
0539 
0540     fCagewall_log = new G4LogicalVolume(cagewall_box,Cu,"cagewall_log",0,0,0);  //tbc
0541     fCagewall_phys = new G4PVPlacement(
0542       0,
0543       G4ThreeVector(22.875*mm,19.3103311*mm,-36.5027*mm),
0544       fCagewall_log,
0545       "cagewall1",
0546       fExperimentalHall_log,
0547       false,
0548       0);
0549 
0550     ///and the other 5 pieces
0551     fCagewall2_phys = new G4PVPlacement(
0552       0,
0553       G4ThreeVector(22.875*mm,-19.3103311*mm,-36.5027*mm),
0554       fCagewall_log,
0555       "cagewall2",
0556       fExperimentalHall_log,
0557       false,
0558       0);
0559 
0560     G4RotationMatrix wallrotm = G4RotationMatrix();
0561 
0562     wallrotm.rotateZ(-60*deg);
0563     G4ThreeVector wallposition3 = G4ThreeVector(5.2857373*mm,29.4654967*mm,-36.5027*mm);
0564     G4Transform3D walltransform3 = G4Transform3D(wallrotm,wallposition3);
0565     fCagewall3_phys = new G4PVPlacement(walltransform3,fCagewall_log,"cagewall3",fExperimentalHall_log, true, 0);
0566 
0567     G4ThreeVector wallposition4 = G4ThreeVector(-28.1607373*mm,10.1551656*mm,-36.5027*mm);
0568     G4Transform3D walltransform4 = G4Transform3D(wallrotm,wallposition4);
0569     fCagewall4_phys = new G4PVPlacement(walltransform4,fCagewall_log,"cagewall4",fExperimentalHall_log, true, 0);
0570 
0571     wallrotm.rotateZ(120*deg);
0572     G4ThreeVector wallposition5 = G4ThreeVector(-28.1607373*mm,-10.1551656*mm,-36.5027*mm);
0573     G4Transform3D walltransform5 = G4Transform3D(wallrotm,wallposition5);
0574     fCagewall5_phys = new G4PVPlacement(walltransform5,fCagewall_log,"cagewall5",fExperimentalHall_log, true, 0);
0575 
0576     G4ThreeVector wallposition6 = G4ThreeVector(5.2857373*mm,-29.4654967*mm,-36.5027*mm);
0577     G4Transform3D walltransform6 = G4Transform3D(wallrotm,wallposition6);
0578     fCagewall6_phys = new G4PVPlacement(walltransform6,fCagewall_log,"cagewall6",fExperimentalHall_log, true, 0);
0579 
0580     //-----------------------miniwalls
0581     G4double minicagewall_x = 15.875*mm;
0582     G4double minicagewall_y = 1*mm;
0583 
0584     auto *minicagewall_box = new G4Box("minicagewall_box",minicagewall_x*0.5,minicagewall_y*0.5,cagewall_z*0.5);
0585     fMinicagewall_log = new G4LogicalVolume(minicagewall_box,Cu,"minicagewall_log",0,0,0);//tbc
0586     fMinicagewall_phys = new G4PVPlacement(
0587       0,
0588       G4ThreeVector(33.8125*mm,0*mm,-36.5027*mm),
0589       fMinicagewall_log,
0590       "minicagewall1",
0591       fExperimentalHall_log,
0592       false,
0593       0);
0594 
0595     G4RotationMatrix wallrotm2 = G4RotationMatrix();
0596 
0597     wallrotm2.rotateZ(-60*deg);
0598     G4ThreeVector miniwallposition2 = G4ThreeVector(-16.90625*mm,29.282484*mm,-36.5027*mm);
0599     G4Transform3D miniwalltransform2 = G4Transform3D(wallrotm2,miniwallposition2);
0600     fMinicagewall2_phys = new G4PVPlacement(miniwalltransform2,fMinicagewall_log,"minicagewall2",fExperimentalHall_log, true, 0);
0601 
0602     wallrotm2.rotateZ(-60*deg);
0603     G4ThreeVector miniwallposition3 = G4ThreeVector(-16.90625*mm,-29.282484*mm,-36.5027*mm);
0604     G4Transform3D miniwalltransform3 = G4Transform3D(wallrotm2,miniwallposition3);
0605     fMinicagewall3_phys = new G4PVPlacement(miniwalltransform3,fMinicagewall_log,"minicagewall3",fExperimentalHall_log, true, 0);
0606 
0607     //--------------extwalls
0608     G4double extcagewall_x = 1.85*mm;
0609     G4double extcagewall_y = 37.75*mm;
0610     G4double extcagewall_z = 65*mm;
0611 
0612     auto *extcagewall_box = new G4Box("extcagewall_box",extcagewall_x*0.5,extcagewall_y*0.5,extcagewall_z*0.5);
0613     fExtcagewall_log = new G4LogicalVolume(extcagewall_box,Cu,"extcagewall_log",0,0,0);
0614     G4RotationMatrix wallrotm3 = G4RotationMatrix();
0615     wallrotm3.rotateZ(-30*deg);
0616     G4ThreeVector extwallposition = G4ThreeVector(-35.0724512*mm,20.2490891*mm,-36.5027*mm);
0617     G4Transform3D extwalltransform = G4Transform3D(wallrotm3,extwallposition);
0618     fExtcagewall_phys = new G4PVPlacement(extwalltransform,fExtcagewall_log,"extcagewall1",fExperimentalHall_log, true, 0);
0619 
0620     G4ThreeVector extwallposition2 = G4ThreeVector(35.0724512*mm,-20.2490891*mm,-36.5027*mm);
0621     G4Transform3D extwalltransform2 = G4Transform3D(wallrotm3,extwallposition2);
0622     fExtcagewall2_phys = new G4PVPlacement(extwalltransform2,fExtcagewall_log,"extcagewall2",fExperimentalHall_log, true, 0);
0623 
0624     //--------------extboards
0625     G4double extboard_x = 0.5*mm;
0626     G4double extboard_y = 36.5*mm;
0627     G4double extboard_z = 64.5*mm;
0628 
0629     auto *extboard_box = new G4Box("extboard_box",extboard_x*0.5,extboard_y*0.5,extboard_z*0.5);
0630     fExtboard_log = new G4LogicalVolume(extboard_box,Si,"extboard_log",0,0,0);
0631     G4ThreeVector extboardposition = G4ThreeVector(37.932*mm,-21.9*mm,-36.253*mm);
0632     G4Transform3D extboardtransform = G4Transform3D(wallrotm3,extboardposition);
0633     fExtboard_phys = new G4PVPlacement(extboardtransform,fExtboard_log,"extboard1",fExperimentalHall_log, true, 0);
0634 
0635     G4ThreeVector extboardposition2 = G4ThreeVector(-37.932*mm,21.9*mm,-36.253*mm);
0636     G4Transform3D extboardtransform2 = G4Transform3D(wallrotm3,extboardposition2);
0637     fExtboard2_phys = new G4PVPlacement(extboardtransform2,fExtboard_log,"extboard2",fExperimentalHall_log, true, 0);
0638 
0639     //-------------------------------------------------------------------------------------------------
0640     // --- END OF THE SUPPORTING STRUCTURES. HERE: STAGES OF THE CRYOSTAT -----------------------------
0641 
0642     //-------------------------------------------------------------------------------------------------
0643     //----------------------------------------   First thermal shield  -----------------------------------------
0644 
0645     auto *FirstShield_botplate = new G4Tubs("Tube_FirstShield_botplate", 0.*mm, 80*mm, 1*mm*0.5, 0*deg, 360*deg);
0646     G4LogicalVolume* FirstShield_botplate_log = new G4LogicalVolume(FirstShield_botplate,Cryoperm,"FirstShield_botplate_log",0,0,0);
0647     fFirstShield_botplate_phys = new G4PVPlacement(
0648       0,
0649       G4ThreeVector(0,0,-101*mm),
0650       FirstShield_botplate_log,
0651       "FirstShield_botplate",
0652       fExperimentalHall_log,
0653       false,
0654       0);
0655 
0656     //------------------------
0657     auto *FirstShield_side = new G4Tubs("Tube_FirstShield_side", 79*mm, 80*mm, 145*mm*0.5, 0*deg, 360*deg);
0658     G4LogicalVolume* FirstShield_side_log = new G4LogicalVolume(FirstShield_side,Cryoperm,"FirstShield_side_log",0,0,0);
0659     fFirstShield_side_phys = new G4PVPlacement(
0660       0,
0661       G4ThreeVector(0,0,-28*mm),
0662       FirstShield_side_log,
0663       "FirstShield_side",
0664       fExperimentalHall_log,
0665       false,
0666       0);
0667 
0668     //---------------------------
0669     auto *FirstShield_topplate = new G4Tubs("Tube_FirstShield_topplate", 31.85*mm, 80*mm, 1*mm*0.5, 0*deg, 360*deg);
0670     G4LogicalVolume* FirstShield_topplate_log = new G4LogicalVolume(FirstShield_topplate,Cryoperm,"FirstShield_topplate_log",0,0,0);
0671     fFirstShield_topplate_phys = new G4PVPlacement(
0672       0,
0673       G4ThreeVector(0,0,45*mm),
0674       FirstShield_topplate_log,
0675       "FirstShield_topplate",
0676       fExperimentalHall_log,
0677       false,
0678       0);
0679 
0680     //------------------------------
0681     auto *FirstShield_topcyl = new G4Tubs("Tube_FirstShield_topcyl", 31.85*mm, 32.85*mm, 74*mm*0.5, 0*deg, 360*deg);
0682     G4LogicalVolume* FirstShield_topcyl_log = new G4LogicalVolume(FirstShield_topcyl,Cryoperm,"FirstShield_topcyl_log",0,0,0);
0683     fFirstShield_topcyl_phys = new G4PVPlacement(
0684       0,
0685       G4ThreeVector(0,0,82.5*mm),
0686       FirstShield_topcyl_log,
0687       "FirstShield_topcyl",
0688       fExperimentalHall_log,
0689       false,
0690       0);
0691 
0692     //-------------------------------------------------------------------------------------------------
0693     //------------------------------------------   Ring  ----------------------------------------------
0694 
0695     // This solid has a complex shape, filled with holes and supporting beams. Since it is not in direct sight of
0696     // the detector, it can be simplified as a ring-like shape.
0697 
0698     // The material has been defined as a custom Al with density equal to the average density in the original solid
0699     G4double hightOfRing = 85*mm;
0700     auto *Ring = new G4Tubs("Ring_tubs", 80*mm, 97.1*mm, hightOfRing*0.5, 0*deg, 360*deg);
0701 
0702     // Three boxes are used for a boolean subtraction, cutting 3 sections of the ring
0703     G4double cuts_x = 38.781347139*mm;
0704     G4double cuts_y = 116.620103593*mm;
0705     G4double cuts_z = 85.1*mm;
0706 
0707     auto *cuts_box = new G4Box("cuts_box",cuts_x*0.5,cuts_y*0.5,cuts_z*0.5);
0708 
0709     G4ThreeVector cutspos = G4ThreeVector(-105.055643631*mm,0,0);
0710     G4SubtractionSolid* Ringsub = new G4SubtractionSolid("Ringsub",Ring,cuts_box,0,cutspos);
0711 
0712     auto *cutsrotm = new G4RotationMatrix();
0713     cutsrotm->rotateZ(60*deg);
0714     G4ThreeVector cutspos2 = G4ThreeVector(52.527821885*mm,-90.980856208*mm,0);
0715     G4SubtractionSolid* Ringsub2 = new G4SubtractionSolid("Ringsub2",Ringsub,cuts_box,cutsrotm,cutspos2);
0716     cutsrotm->rotateZ(60*deg);
0717     G4ThreeVector cutspos3 = G4ThreeVector(52.527821885*mm,90.980856208*mm,0);
0718     auto *Ringsub3 = new G4SubtractionSolid("Ringsub3",Ringsub2,cuts_box,cutsrotm,cutspos3);
0719     auto *Ring_log = new G4LogicalVolume(Ringsub3,RingAl,"Ring_log",0,0,0);//tbc
0720     fRing_phys = new G4PVPlacement(
0721       0,
0722       G4ThreeVector(0.,0.,-22*mm),
0723       Ring_log,
0724       "Ring",
0725       fExperimentalHall_log,
0726       false,
0727       0);
0728 
0729     //-------------------------------------------------------------------------------------------------
0730     //----------------------------------------   Second thermal shield  -----------------------------------------
0731     // This is another irregular and complex shape derived from a CAD engineering model that was simplified for Geant4 implementation
0732 
0733     // Define the overall shape and bottom plate defining the base points to extrude
0734     std::vector<G4TwoVector> newShape(6);
0735     newShape[0] = G4TwoVector(58.936*mm, 154.115*mm);
0736     newShape[1] = G4TwoVector(104*mm, 128.098*mm);
0737     newShape[2] = G4TwoVector(104*mm, -128.098*mm);
0738     newShape[3] = G4TwoVector(58.936*mm, -154.115*mm);
0739     newShape[4] = G4TwoVector(-162.936*mm, -26.018*mm);
0740     newShape[5] = G4TwoVector(-162.936*mm, 26.018*mm);
0741 
0742     // ------------------------------------------- the lower plate  -------------------------------------------
0743     // Extrusion of the solid defined by the 6 points above
0744     auto *MyShape = new G4ExtrudedSolid("MyShape", newShape, 2.65*0.5*mm, G4TwoVector(0, 0), 1.0, G4TwoVector(0, 0), 1.0);
0745 
0746     // Inserting a hole in the plate
0747     auto *MyHole = new G4Tubs("MyHole", 0, 19*mm, 3*mm*0.5, 0*deg, 360*deg);
0748     G4ThreeVector holepos = G4ThreeVector(0,0,0);
0749     auto *SecondShieldbotPlate = new G4SubtractionSolid("SecondShieldbotPlate_sub",MyShape,MyHole,0,holepos);
0750     auto *SecondShieldbotPlate_log = new G4LogicalVolume(SecondShieldbotPlate,Al,"SecondShieldbotPlate_log",0,0,0);
0751     fSecondShieldbotPlate_phys = new G4PVPlacement(
0752       0,
0753       G4ThreeVector(0,0,-110.178*mm),
0754       SecondShieldbotPlate_log,
0755       "SecondShieldbotPlate",
0756       fExperimentalHall_log,
0757       false,
0758       0);
0759 
0760     //---------------------------------------------------------------------------------------------------
0761     //------------------------------------------ the central part ---------------------------------------
0762 
0763     // Definitino of the central block
0764     auto *MyShape2 = new G4ExtrudedSolid("MyShape2", newShape, 215.35*0.5*mm, G4TwoVector(0, 0), 1.0, G4TwoVector(0, 0), 1.0);
0765 
0766     // The central part needs to be empty inside, so we define 6 new points for the subtraction of the central area
0767     std::vector<G4TwoVector> newHole(6);
0768     newHole[0] = G4TwoVector(58.936*mm, 149.762*mm);
0769     newHole[1] = G4TwoVector(100.23*mm, 125.921*mm);
0770     newHole[2] = G4TwoVector(100.23*mm, -125.921*mm);
0771     newHole[3] = G4TwoVector(58.936*mm, -149.762*mm);
0772     newHole[4] = G4TwoVector(-159.166*mm, -23.841*mm);
0773     newHole[5] = G4TwoVector(-159.166*mm, 23.841*mm);
0774 
0775     // Extrusion of the subtraction solid
0776     auto *MyInnerShape = new G4ExtrudedSolid("MyInnerShape", newHole, 216*0.5*mm, G4TwoVector(0, 0), 1.0, G4TwoVector(0, 0), 1.0);
0777 
0778     // creation of the central part: subtract the  subtraction solid from the central block
0779     auto *SecondShieldside = new G4SubtractionSolid("SecondShieldside_sub",MyShape2,MyInnerShape,0,holepos);
0780     auto *SecondShieldside_log = new G4LogicalVolume(SecondShieldside,Al,"SecondShieldside_log",0,0,0);
0781     fSecondShieldside_phys = new G4PVPlacement(
0782       0,
0783       G4ThreeVector(0,0,-1.178*mm),
0784       SecondShieldside_log,
0785       "SecondShieldside",
0786       fExperimentalHall_log,
0787       false,
0788       0);
0789 
0790     //-------------------------------------- top plate cover ---------------------------------------
0791     G4ExtrudedSolid *MyShape3 = new G4ExtrudedSolid("MyShape3", newShape, 10.87*0.5*mm, G4TwoVector(0, 0), 1.0, G4TwoVector(0, 0), 1.0);
0792     auto *MyHole2 = new G4Tubs("MyHole2", 0, 36.85*mm, 11*mm*0.5, 0*deg, 360*deg);
0793     auto *SecondShieldtopPlate = new G4SubtractionSolid("SecondShieldtopPlate_sub",MyShape3,MyHole2,0,holepos);
0794     auto *SecondShieldtopPlate_log = new G4LogicalVolume(SecondShieldtopPlate,Al,"SecondShieldtopPlate_log",0,0,0);
0795     fSecondShieldtopPlate_phys = new G4PVPlacement(
0796       0,
0797       G4ThreeVector(0,0,111.932*mm),
0798       SecondShieldtopPlate_log,
0799       "SecondShieldtopPlate",
0800       fExperimentalHall_log,
0801       false,
0802       0);
0803 
0804     //--------------------------------------
0805     auto *SecondShieldshield_topcyl = new G4Tubs("SecondShieldshield", 36.85*mm, 39*mm, 12*mm*0.5, 0*deg, 360*deg);
0806     auto *SecondShieldshield_topcyl_log = new G4LogicalVolume(SecondShieldshield_topcyl,Al,"SecondShieldshield_topcyl_log",0,0,0);
0807     fSecondShieldshield_topcyl_phys = new G4PVPlacement(
0808       0,
0809       G4ThreeVector(0,0,123.367*mm),
0810       SecondShieldshield_topcyl_log,
0811       "SecondShieldshield_topcyl",
0812       fExperimentalHall_log,
0813       false,
0814       0);
0815 
0816     //------------------------------------------------------------------------------------------------------
0817     //-------------------------------------    EXTERNAL ZONE     -------------------------------------------
0818 
0819     //------------------------------------------------------------------------------------------------------
0820     //---------------------------------------- Third thermal shield ---------------------------------------------------
0821     G4double TopConeDOWNradius = 174.6*mm;
0822     G4double TopConeUPradius = 93*mm;
0823     G4double TopConeheight = 40*mm;
0824     G4double SideHeight = 280*mm;
0825     G4double ConeDOWNradius = 80*mm;
0826     G4double Conethick = 0.4*mm;
0827     G4double ConeUPradius = 174.6*mm;
0828     G4double Coneheight = 40*mm;
0829 
0830     //---------------
0831     auto *ThirdShieldside = new G4Tubs("ThirdShieldside_tubs", TopConeDOWNradius, TopConeDOWNradius+Conethick, SideHeight*0.5, 0*deg, 360*deg);
0832     G4LogicalVolume* ThirdShieldside_log = new G4LogicalVolume(ThirdShieldside,Al,"ThirdShieldside_log",0,0,0);
0833     fThirdShieldside_phys = new G4PVPlacement(
0834       0,
0835       G4ThreeVector(0,0,0),
0836       ThirdShieldside_log,
0837       "ThirdShieldside",
0838       fExperimentalHall_log,
0839       false,
0840       0);
0841 
0842     //-------------------
0843     auto *ThirdShieldtopCone = new G4Cons("ThirdShieldtopCone_cons", TopConeDOWNradius,Conethick+TopConeDOWNradius,TopConeUPradius,TopConeUPradius+Conethick, TopConeheight*0.5, 0*deg, 360*deg);
0844     auto *ThirdShieldtopCone_log = new G4LogicalVolume(ThirdShieldtopCone,Al,"ThirdShieldtopCone_log",0,0,0);
0845     fThirdShieldtopCone_phys = new G4PVPlacement(
0846       0,
0847       G4ThreeVector(0.,0.,(SideHeight+TopConeheight)*0.5),
0848       ThirdShieldtopCone_log,
0849       "ThirdShieldtopCone",
0850       fExperimentalHall_log,
0851       false,
0852       0);
0853 
0854     //-------------------
0855     auto *ThirdShieldbotCone = new G4Cons("ThirdShieldbotCone_cons", ConeDOWNradius,Conethick+ConeDOWNradius,ConeUPradius,ConeUPradius+Conethick, Coneheight*0.5, 0*deg, 360*deg);
0856     auto *ThirdShieldbotCone_log = new G4LogicalVolume(ThirdShieldbotCone,Al,"ThirdShieldbotCone_log",0,0,0);
0857     fThirdShieldbotCone_phys = new G4PVPlacement(
0858       0,
0859       G4ThreeVector(0.,0.,(-SideHeight-Coneheight)*0.5),
0860       ThirdShieldbotCone_log,
0861       "ThirdShieldbotCone",
0862       fExperimentalHall_log,
0863       false,
0864       0);
0865 
0866     //-------------------
0867     auto *ThirdShieldbotPlate = new G4Tubs("ThirdShieldbotPlate_tubs", 0*mm, Conethick+ConeDOWNradius,Conethick*0.5, 0*deg, 360*deg);
0868     auto *ThirdShieldbotPlate_log = new G4LogicalVolume(ThirdShieldbotPlate,Al,"ThirdShieldbotPlate_log",0,0,0);
0869     fThirdShieldbotPlate_phys = new G4PVPlacement(
0870       0,
0871       G4ThreeVector(0,0,(-SideHeight-Conethick)*0.5-Coneheight),
0872       ThirdShieldbotPlate_log,
0873       "ThirdShieldbotPlate",
0874       fExperimentalHall_log,
0875       false,
0876       0);
0877 
0878     //----------------------------------------------------------------------------------------------------------------
0879     //-------------------------------------------------- External layer of the Cryostat --------------------------------------------------
0880     //----------------------------------------------------------------------------------------------------------------
0881     G4double sideradius = 200*mm;
0882     G4double midsidethick = 8.8*mm;
0883     G4double midsideheigth = 120*mm;
0884     auto *CryostatmidSide = new G4Tubs("CryostatmidSide_tubs", sideradius, sideradius+midsidethick, midsideheigth*0.5, 0*deg, 360*deg);
0885     auto *CryostatmidSide_log = new G4LogicalVolume(CryostatmidSide,Al,"CryostatmidSide_log",0,0,0);
0886     fCryostatmidSide_phys = new G4PVPlacement(
0887       0,
0888       G4ThreeVector(0,0,0),
0889       CryostatmidSide_log,
0890       "CryostatmidSide",
0891       fExperimentalHall_log,
0892       false,
0893       0);
0894 
0895     //---------------
0896     G4double topsidethick = 6.5*mm;
0897     G4double topsideheigth = 85*mm;
0898     auto *CryostattopSide = new G4Tubs("CryostattopSide_tubs", sideradius, sideradius+topsidethick, topsideheigth*0.5, 0*deg, 360*deg);
0899     auto *CryostattopSide_log = new G4LogicalVolume(CryostattopSide,Al,"CryostattopSide_log",0,0,0);
0900     fCryostattopSide_phys = new G4PVPlacement(
0901       0,
0902       G4ThreeVector(0,0,midsideheigth*0.5+topsideheigth*0.5),
0903       CryostattopSide_log,
0904       "CryostattopSide",
0905       fExperimentalHall_log,
0906       false,
0907       0);
0908 
0909     //-------------------
0910     ConeUPradius = 97*mm;
0911     Coneheight = 75*mm;
0912     auto *CryostattopCone = new G4Cons("CryostattopCone_cons", sideradius,topsidethick+sideradius,ConeUPradius,ConeUPradius+topsidethick, Coneheight*0.5, 0*deg, 360*deg);
0913     auto *CryostattopCone_log = new G4LogicalVolume(CryostattopCone,Al,"CryostattopCone_log",0,0,0);
0914     fCryostattopCone_phys = new G4PVPlacement(
0915       0,
0916       G4ThreeVector(0.,0.,midsideheigth*0.5+topsideheigth+Coneheight*0.5),  // translation position
0917       CryostattopCone_log,
0918       "CryostattopCone",
0919       fExperimentalHall_log,
0920       false,
0921       0);
0922 
0923     //---------------
0924     G4double botsideheigth = 85*mm;
0925     auto *CryostatbotSide = new G4Tubs("CryostatbotSide_tubs", sideradius, sideradius+topsidethick, botsideheigth*0.5, 0*deg, 360*deg);
0926     auto *CryostatbotSide_log = new G4LogicalVolume(CryostatbotSide,Al,"CryostatbotSide_log",0,0,0);
0927     fCryostatbotSide_phys = new G4PVPlacement(
0928       0,
0929       G4ThreeVector(0,0,-midsideheigth*0.5-botsideheigth*0.5),
0930       CryostatbotSide_log,
0931       "CryostatbotSide",
0932       fExperimentalHall_log,
0933       false,
0934       0);
0935 
0936     //-------------------
0937     ConeDOWNradius = 120*mm;
0938     auto *CryostatbotCone = new G4Cons("CryostatbotCone_cons", ConeDOWNradius,topsidethick+ConeDOWNradius,sideradius,sideradius+topsidethick, Coneheight*0.5, 0*deg, 360*deg);
0939     auto *CryostatbotCone_log = new G4LogicalVolume(CryostatbotCone,Al,"CryostatbotCone_log",0,0,0);
0940     fCryostatbotCone_phys = new G4PVPlacement(
0941       0,
0942       G4ThreeVector(0.,0.,-midsideheigth*0.5-botsideheigth-Coneheight*0.5), // translation position
0943       CryostatbotCone_log,
0944       "CryostatbotCone",
0945       fExperimentalHall_log,
0946       false,
0947       0);
0948 
0949     //---------------------
0950     auto *CryostatbotPlate = new G4Tubs("CryostatbotPlate_tubs", 0*mm, ConeDOWNradius, midsidethick*0.5, 0*deg, 360*deg);
0951     auto *CryostatbotPlate_log = new G4LogicalVolume(CryostatbotPlate,Al,"CryostatbotPlate_log",0,0,0);
0952     fCryostatbotPlate_phys = new G4PVPlacement(
0953       0,
0954       G4ThreeVector(0,0,-midsideheigth*0.5-botsideheigth-Coneheight+midsidethick*0.5),  // translation position
0955       CryostatbotPlate_log,
0956       "CryostatbotPlate",
0957       fExperimentalHall_log,
0958       false,
0959       0);
0960 
0961     //------------------------------------------------------------------------------------------------------
0962     //-------------------------------------  radiation filter   --------------------------------------------
0963     //------------------------------------------------------------------------------------------------------
0964     G4double halfhightOfAlFilter = 20*0.5*nm;
0965     G4double mesh_thickness = 80*um;
0966     G4double filtercarrierthickness = 5*mm;
0967     G4double outerRadiusOfFilter = 128*0.5*mm;
0968     G4double ZposFilter = 180*mm;
0969 
0970     auto *AlFilter = new G4Tubs("Filter", 0, outerRadiusOfFilter, halfhightOfAlFilter, 0.*deg, 360.*deg);
0971     auto *AlFilter_log = new G4LogicalVolume(AlFilter,Al,"AlFilter_log",0,0,0);
0972     fAlFilter_phys = new G4PVPlacement(nullptr,G4ThreeVector(0.,0.,ZposFilter), AlFilter_log, "AlFilter" ,fExperimentalHall_log,false,0);
0973 
0974     //------step limiter filter
0975     AlFilter_log->SetUserLimits(fStepLimitAlfilta);
0976 
0977     //----- mesh: Nb
0978     auto *Mesh = new G4Tubs("meshcage", 0, outerRadiusOfFilter+3.3*mm, mesh_thickness*0.5 , 0.*deg, 360.*deg);
0979     fMesh_log = new G4LogicalVolume(Mesh,vacuum,"Mesh_log");   //vacuum, it's the mother volume and not the grid
0980     G4double meshPos_z = ZposFilter-halfhightOfAlFilter-mesh_thickness*0.5;
0981     fMesh_phys = new G4PVPlacement(nullptr, G4ThreeVector(DetPos_x,DetPos_y,meshPos_z),fMesh_log,"meshphys",fExperimentalHall_log, false, 0);
0982 
0983     //////// mesh pixels (grid support)
0984     G4double half_x1 = 4827/2.*um;
0985     G4double half_x2 = 4827/2.*um;
0986     G4double half_x3 = 4880/2.*um;
0987     G4double half_x4 = 4880/2.*um;
0988     G4double half_y1 = 80/2.*um;
0989     G4double half_y2 = 80/2.*um;
0990     G4double dZ = 26.50/2.*um;
0991 
0992     G4double L1 = half_x1;
0993     G4double L3 = dZ;
0994 
0995     // create the trapezoids for the element of the grid
0996     auto *trapezoid_A = new G4Trap("Trapezoid_A",dZ,0,0,half_y1,half_x1,half_x2,0,half_y2,half_x3,half_x4,0);
0997     auto *trapezoid_B = new G4Trap("Trapezoid_B",dZ,0,0,half_y1,half_x1,half_x2,0,half_y2,half_x3,half_x4,0);
0998     auto *trapezoid_C = new G4Trap("Trapezoid_C",dZ,0,0,half_y1,half_x1,half_x2,0,half_y2,half_x3,half_x4,0);
0999     auto *trapezoid_D = new G4Trap("Trapezoid_D",dZ,0,0,half_y1,half_x1,half_x2,0,half_y2,half_x3,half_x4,0);
1000 
1001     // create their rotation matrices and placement vectors
1002     auto *rotmat_A = new G4RotationMatrix();
1003     auto *rotmat_B = new G4RotationMatrix();
1004     auto *rotmat_C = new G4RotationMatrix();
1005     auto *rotmat_D = new G4RotationMatrix();
1006     rotmat_A->rotateX(90.*deg);
1007     rotmat_B->rotateX(90.*deg);
1008     rotmat_B->rotateY(-90.*deg);
1009     rotmat_C->rotateX(270.*deg);
1010     rotmat_D->rotateX(90.*deg);
1011     rotmat_D->rotateY(90.*deg);
1012     G4ThreeVector pos_trap_A = G4ThreeVector(0,L1+L3,meshPos_z);
1013     G4ThreeVector pos_trap_B = G4ThreeVector(L1+L3,0,meshPos_z);
1014     G4ThreeVector pos_trap_C = G4ThreeVector(0,-L1-L3,meshPos_z);
1015     G4ThreeVector pos_trap_D = G4ThreeVector(-L1-L3,0,meshPos_z);
1016 
1017     //Test: create their logical and physical volumes
1018     fTrapezoid_A_log = new G4LogicalVolume(trapezoid_A,SS,"trapezoid_A_log");
1019     fTrapezoid_B_log = new G4LogicalVolume(trapezoid_B,SS,"trapezoid_B_log");
1020     fTrapezoid_C_log = new G4LogicalVolume(trapezoid_C,SS,"trapezoid_C_log");
1021     fTrapezoid_D_log = new G4LogicalVolume(trapezoid_D,SS,"trapezoid_D_log");
1022 
1023     G4ThreeVector pos_munion_base = G4ThreeVector(0,0,0);
1024     auto *rotmat_final = new G4RotationMatrix();
1025     rotmat_final->rotateX(0.*deg);
1026     G4Transform3D transf_base = G4Transform3D(*rotmat_final, pos_munion_base);
1027 
1028     G4int index = 0;
1029     G4double coordx = 0;
1030     G4double coordy = 0;
1031     const G4int num = 13;
1032     G4double distance = 0;
1033 
1034     G4ThreeVector pos_base = G4ThreeVector(0,0,0);
1035     G4ThreeVector posA = G4ThreeVector(0,0,0); // the z coord is 0 because it will refer to Mesh_log
1036     G4ThreeVector posB = G4ThreeVector(0,0,0);
1037     G4ThreeVector posC = G4ThreeVector(0,0,0);
1038     G4ThreeVector posD = G4ThreeVector(0,0,0);
1039 
1040     std::vector<G4VPhysicalVolume*> phys_array;
1041     for (int i=-num; i<=num; i++)
1042     {
1043       for (int j=-num; j<=num; j++)
1044       {
1045         std::string sA = "trapezoidA_";
1046         std::string sB = "trapezoidB_";
1047         std::string sC = "trapezoidC_";
1048         std::string sD = "trapezoidD_";
1049 
1050         std::string index_str = std::to_string(index);
1051         sA += index_str;
1052         sB += index_str;
1053         sC += index_str;
1054         sD += index_str;
1055 
1056         coordx = i*half_x3*2;
1057         coordy = j*half_x3*2;
1058 
1059         distance = std::sqrt(coordx*coordx + coordy*coordy);
1060 
1061         if (distance < outerRadiusOfFilter)
1062         {
1063           pos_base = G4ThreeVector(coordx,coordy,meshPos_z);
1064           posA = G4ThreeVector(coordx,coordy+L1+L3,0); // the z coord is 0 because it will refer to fMesh_log
1065           posB = G4ThreeVector(coordx+L1+L3,coordy,0);
1066           posC = G4ThreeVector(coordx,coordy-L1-L3,0);
1067           posD = G4ThreeVector(coordx-L1-L3,coordy,0);
1068 
1069           fTrapezoid_A_phys = new G4PVPlacement(rotmat_A,posA,fTrapezoid_A_log,sA,fMesh_log, false, 0);
1070           fTrapezoid_B_phys = new G4PVPlacement(rotmat_B,posB,fTrapezoid_B_log,sB,fMesh_log, false, 0);
1071           fTrapezoid_C_phys = new G4PVPlacement(rotmat_C,posC,fTrapezoid_C_log,sC,fMesh_log, false, 0);
1072           fTrapezoid_D_phys = new G4PVPlacement(rotmat_D,posD,fTrapezoid_D_log,sD,fMesh_log, false, 0);
1073 
1074           phys_array.push_back(fTrapezoid_A_phys);
1075           phys_array.push_back(fTrapezoid_B_phys);
1076           phys_array.push_back(fTrapezoid_C_phys);
1077           phys_array.push_back(fTrapezoid_D_phys);
1078           index += 1;
1079         }
1080       }
1081     }
1082 
1083     auto *filtercarrier = new G4Tubs("filtercarrier_tubs", outerRadiusOfFilter,outerRadiusOfFilter+3.85*mm ,filtercarrierthickness*0.5,0.*deg,360.*deg);
1084     auto *filtercarrier_log = new G4LogicalVolume(filtercarrier,Al,"filtercarrier_log",0,0,0);
1085     fFiltercarrier_phys = new G4PVPlacement(nullptr,G4ThreeVector(0.,0.,meshPos_z+mesh_thickness*0.5+filtercarrierthickness*0.5),filtercarrier_log,"filtercarrier",fExperimentalHall_log,false,0);
1086 
1087     //------------------------------------------------------------------------------------------------------
1088     //----------------------------------------   aperture cylinder   ---------------------------------------
1089     //------------------------------------------------------------------------------------------------------
1090     //300K piece
1091     //G4double ACinnerDOWNradius = 106*mm;
1092     G4double ACinnerUPradius = 67.8644*mm;
1093     G4double ACthick = 1*mm;
1094     G4double ACheight = midsideheigth*0.5+topsideheigth+Coneheight-ZposFilter-filtercarrierthickness;
1095 
1096     //ZposFilter
1097     auto *AC = new G4Cons("AC_cons",ACinnerUPradius-ACthick,ACinnerUPradius,ConeUPradius-ACthick,ConeUPradius,ACheight*0.5,0*deg,360*deg);
1098     auto *AC_log = new G4LogicalVolume(AC,Ti,"AC_log",0,0,0);
1099     fAC_phys = new G4PVPlacement(
1100       0,
1101       G4ThreeVector(0.,0.,midsideheigth*0.5+topsideheigth+Coneheight-ACheight*0.5),
1102       AC_log,
1103       "AC",
1104       fExperimentalHall_log,
1105       false,
1106       0);
1107 
1108     //-----inner coating
1109     auto *ACIC = new G4Cons("ACIC_cons",ACinnerUPradius-ACthick-5*um,ACinnerUPradius-ACthick,ConeUPradius-ACthick-5*um,ConeUPradius-ACthick,ACheight*0.5,0*deg,360*deg);
1110     auto *ACIC_log = new G4LogicalVolume(ACIC,Au,"ACIC_log",0,0,0);
1111     fACIC_phys = new G4PVPlacement(
1112       0,
1113       G4ThreeVector(0.,0.,midsideheigth*0.5+topsideheigth+Coneheight-ACheight*0.5),
1114       ACIC_log,
1115       "ACIC",
1116       fExperimentalHall_log,
1117       false,
1118       0);
1119 
1120     //------------------------------------------------------------------------------------------------------
1121     //------------------------------    The Al sphere representing the spacecraft     ----------------------
1122     //------------------------------------------------------------------------------------------------------
1123     auto *sphere = new G4Sphere("sphere_sphere",26*cm,27*cm,0.,twopi,0.,pi);
1124     fSphere_log = new G4LogicalVolume(sphere,Al,"sphere_log");
1125     fSphere_phys = new G4PVPlacement(nullptr,G4ThreeVector(0.,0.,0*mm),fSphere_log,"sphere",fExperimentalHall_log,false,0);
1126 
1127     //------------------------------------------------------------------------------------------------------
1128     //---------------------    regions assignment: closer to the detector, lower the Ecut     --------------
1129     //------------------------------------------------------------------------------------------------------
1130     // everything directly seen by the detector
1131     InnerRegion->AddRootLogicalVolume(fElement_log);
1132     InnerRegion->AddRootLogicalVolume(fDetector_log);
1133     InnerRegion->AddRootLogicalVolume(fBipxl_log);
1134     InnerRegion->AddRootLogicalVolume(fMembranepxl_log);
1135     InnerRegion->AddRootLogicalVolume(fGridpiece_log);
1136     InnerRegion->AddRootLogicalVolume(fWafer_log);
1137     InnerRegion->AddRootLogicalVolume(fACDpxl_log);
1138     InnerRegion->AddRootLogicalVolume(AlFilter_log);  // it was in the intermediate region
1139     InnerRegion->AddRootLogicalVolume(ACIC_log);
1140 
1141     fWorld_phys = fExperimentalHall_phys;
1142   }
1143   else
1144   {
1145     G4cout << "Build geometry from GDML file: " << fReadFile << G4endl;
1146     G4VPhysicalVolume* fWorldPhysVol;
1147     fParser.Read(fReadFile);
1148     fWorldPhysVol = fParser.GetWorldVolume();
1149     fWorld_log =  fWorldPhysVol->GetLogicalVolume();
1150     G4int num_volumes = 9;
1151     auto *inner_volumes = new G4String[num_volumes];
1152     inner_volumes[0] = "element_log"; inner_volumes[1] = "Detector_log"; inner_volumes[2] = "Bipxl_log"; inner_volumes[3] = "membranepxl_log";
1153     inner_volumes[4] = "gridpiece_log"; inner_volumes[5] = "wafer_log"; inner_volumes[6] = "ACDpxl_log"; inner_volumes[7] = "AlFilter_log";
1154     inner_volumes[8] = "ACIC_log";
1155 
1156     G4cout << "Adding volumes to the InnerRegion" << G4endl;
1157     // Add volumes to the InnerRegion
1158     for (G4int j = 0; j <= num_volumes; j++)
1159     {
1160       for (G4int i = 0; i < (G4int)fWorld_log->GetNoDaughters(); i++)
1161       {
1162         if (fWorld_log->GetDaughter(i)->GetLogicalVolume()->GetName() == inner_volumes[j])
1163         {
1164           InnerRegion->AddRootLogicalVolume(fWorld_log->GetDaughter(i)->GetLogicalVolume());
1165           G4cout << "Added: " << fWorld_log->GetDaughter(i)->GetLogicalVolume()->GetName() << G4endl;
1166         }
1167       }
1168     }
1169 
1170     // Read volume names
1171     auto *pvs = G4PhysicalVolumeStore::GetInstance();
1172     if (pvs == nullptr)
1173     {
1174       G4cout << "PhysicalVolumeStore not accessible" << G4endl;
1175     }
1176     else
1177     {
1178       G4cout << "Volumes imported in the PhysicalVolumeStore. " << G4endl;
1179       G4int length = 0;
1180       length = pvs->size();
1181       for (G4int i= 0; i<length; i++)
1182       {
1183         G4String volName = ((*pvs)[i])->GetName();
1184       }
1185     }
1186     fWorld_phys = fWorldPhysVol;
1187   }
1188 
1189   // Set production cuts
1190   G4ProductionCutsTable::GetProductionCutsTable()->SetEnergyRange(200*eV, 1000*GeV);
1191   auto* InnerCuts = new G4ProductionCuts;
1192   InnerCuts->SetProductionCut(1*mm);
1193   InnerRegion->SetProductionCuts(InnerCuts);
1194 
1195   return fWorld_phys;
1196 }
1197 
1198 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
1199 
1200 void XrayTESdetDetectorConstruction::SetMaxStep(G4double maxStep)
1201 {
1202   if ((fStepLimitAlfilta != nullptr)&&(maxStep>0.)){ fStepLimitAlfilta->SetMaxAllowedStep(maxStep); }
1203   if ((fStepLimitPolyfilta  != nullptr)&&(maxStep>0.)){ fStepLimitPolyfilta->SetMaxAllowedStep(maxStep); }
1204   if ((fStepLimitmembrane  != nullptr)&&(maxStep>0.)){ fStepLimitmembrane->SetMaxAllowedStep(maxStep); }
1205 }
1206 
1207 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
1208 
1209 void XrayTESdetDetectorConstruction::SetReadFile(G4String input_geometry)
1210 {
1211   fReadFile = std::move(input_geometry);
1212 }
1213 
1214 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......