diff --git a/CMakeLists.txt b/CMakeLists.txt index b5d15b9..412d584 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -92,15 +92,15 @@ set(TOP_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}") #Add the include directories. include(${Geant4_USE_FILE}) include_directories(include) -include_directories(dict/include) include_directories(olaInclude) +include_directories(dict/include) +include_directories(/opt/CADmesh/geant4.10.3.3/include) #Add the root dictionary directory. add_subdirectory(dict) #Add the source directories. add_subdirectory(source) -#add_subdirectory(olaSrc) if(BUILD_TOOLS) option(BUILD_TOOLS_NISTLIST "Build NIST library list program." OFF) @@ -118,4 +118,4 @@ if(BUILD_TOOLS_CONVERTER) endif(BUILD_TOOLS_CONVERTER) #Build/install the miscellaneous stuff -add_subdirectory(share) +add_subdirectory(share) \ No newline at end of file diff --git a/dict/def.struct b/dict/def.struct index 47e5605..de1b0c6 100644 --- a/dict/def.struct +++ b/dict/def.struct @@ -57,6 +57,29 @@ short photonComRow Segmented PMT anode row corresponding to the photon center-of END_TYPES END_CLASS +##################################################################### +# nDetImplantOutputStructure +##################################################################### + +BEGIN_CLASS nDetImplantOutput +SHORT Container for NEXTSim simulation variable output +LONG Structure for storing information about NEXTSim primary particles and optical photons produced by scattering +BEGIN_TYPES +u_int nPhotonsTot Total number of scintillation photons produced +u_int nPhotonsDetTot Total number of optical photons detected by both PMTs +double lightBalance Ratio of the difference of left and right TQDC to the sum of left and right TQDC +double photonDetEff Ratio of optical photons detected by a PMT to the total number of photons generated +double barTOF Average of the left and right dynode light pulse phases computed using PolyCFD (in ns) +double barQDC Average of the left and right dynode light pulse integrals +double barMaxADC Average of the left and right dynode light pulse maxima (in ADC channels) +double photonComX Average of the left and right photon center-of-mass X position (in mm) +double photonComY Average of the left and right photon center-of-mass Y position (in mm) +double reconComX Left and right PMT photon center-of-mass along the X-axis computed using Anger Logic reconstruction +double reconComY Left and right PMT photon center-of-mass along the Y-axis computed using Anger Logic reconstruction +short photonComCol Segmented PMT anode column corresponding to the photon center-of-mass for the left and right PMT +short photonComRow Segmented PMT anode row corresponding to the photon center-of-mass for the left and right PMT +END_CLASS + ##################################################################### # nDetMultiOutputStructure ##################################################################### diff --git a/dict/include/LinkDef.h b/dict/include/LinkDef.h index a423d0d..55caacd 100644 --- a/dict/include/LinkDef.h +++ b/dict/include/LinkDef.h @@ -9,6 +9,7 @@ #pragma link C++ class nDetEventStructure+; #pragma link C++ class nDetOutputStructure+; #pragma link C++ class nDetMultiOutputStructure+; +#pragma link C++ class nDetImplantOutputStructure+; #pragma link C++ class nDetDebugStructure+; #pragma link C++ class nDetTraceStructure+; diff --git a/dict/include/nDetStructures.hpp b/dict/include/nDetStructures.hpp index b425544..461f779 100644 --- a/dict/include/nDetStructures.hpp +++ b/dict/include/nDetStructures.hpp @@ -178,6 +178,61 @@ class nDetOutputStructure : public TObject { }; +class nDetImplantOutputStructure : public TObject { + public: + unsigned int nPhotonsTot; ///< Total number of scintillation photons produced + unsigned int nPhotonsDet; ///< Total number of optical photons detected by both PMTs + double lightBalance; ///< Ratio of the difference of left and right TQDC to the sum of left and right TQDC + double tdiff; ///< Time difference between left and right PolyCFD phase (in ns) + double photonTdiff; ///< Time differnence between average photon arrival time for each detector. + double photonDetEff; ///< Ratio of optical photons detected by a PMT to the total number of photons generated + double barTOF; ///< Average of the left and right dynode light pulse phases computed using PolyCFD (in ns) + double barQDC; ///< Average of the left and right dynode light pulse integrals + double barMaxADC; ///< Average of the left and right dynode light pulse maxima (in ADC channels) + bool barTrig; ///< Flag to register if both PMT's would have triggered a digitizer filter + double photonTOF; ///< Average of left and right average photon arrival time (in ns) + double photonComX; ///< Average of the left and right photon center-of-mass X position (in mm) + double photonComY; ///< Average of the left and right photon center-of-mass Y position (in mm) + double reconComX; ///< Left and right PMT photon center-of-mass along the X-axis computed using Anger Logic reconstruction + double reconComY; ///< Left and right PMT photon center-of-mass along the Y-axis computed using Anger Logic reconstruction + short photonComCol; ///< Segmented PMT anode column corresponding to the photon center-of-mass for the left and right PMT + short photonComRow; ///< Segmented PMT anode row corresponding to the photon center-of-mass for the left and right PMT + + // Default constructor + nDetImplantOutputStructure(); + + // Destructor + ~nDetImplantOutputStructure(){} + + /** Set single entry data fields + * @param nPhotonsTot_ Total number of scintillation photons produced + * @param nPhotonsDet_ Total number of optical photons detected by both PMTs + * @param lightBalance_ Ratio of the difference of left and right TQDC to the sum of left and right TQDC + * @param photonDetEff_ Ratio of optical photons detected by a PMT to the total number of photons generated + * @param barTOF_ Average of the left and right dynode light pulse phases computed using PolyCFD (in ns) + * @param barQDC_ Average of the left and right dynode light pulse integrals + * @param barMaxADC_ Average of the left and right dynode light pulse maxima (in ADC channels) + * @param photonComX_ Average of the left and right photon center-of-mass X position (in mm) + * @param photonComY_ Average of the left and right photon center-of-mass Y position (in mm) + * @param reconComX_ Left and right PMT photon center-of-mass along the X-axis computed using Anger Logic reconstruction + * @param reconComY_ Left and right PMT photon center-of-mass along the Y-axis computed using Anger Logic reconstruction + * @param photonComCol_ Segmented PMT anode column corresponding to the photon center-of-mass for the left and right PMT + * @param photonComRow_ Segmented PMT anode row corresponding to the photon center-of-mass for the left and right PMT + */ + + void SetValues(const unsigned int &nPhotonsTot_, const unsigned int &nPhotonsDet_, const double &lightBalance_, const double &tdiff_, const double &photonTdiff_, const double &photonDetEff_, const double &barTOF_, const double &barQDC_, const double &barMaxADC_, const bool &barTrig_, const double &photonTOF_, const double &photonComX_, const double &photonComY_, const double &reconComX_, const double &reconComY_, const short &photonComCol_, const short &photonComRow_); + + // Push back with data + void Append(); + + // Zero all variables + void Zero(); + + /// @cond DUMMY + ClassDef(nDetImplantOutputStructure, 1); // nDetImplantOutput + /// @endcond +}; + /*! \class nDetDebugStructure * \brief Container for NEXTSim simulation variable output * \author Cory R. Thornsbery @@ -362,6 +417,8 @@ class nDetMultiOutputStructure : public TObject { */ void Append(const nDetOutputStructure &output, const short &detID_); + void Append(const nDetImplantOutputStructure &output, const short &detID_); + void Append(const nDetDebugStructure &debug, const short nScatters_); /** Zero all variables diff --git a/dict/source/nDetStructures.cpp b/dict/source/nDetStructures.cpp index 5be4645..1917f17 100644 --- a/dict/source/nDetStructures.cpp +++ b/dict/source/nDetStructures.cpp @@ -128,6 +128,71 @@ void nDetOutputStructure::Zero(){ photonComRow = 0; } +/////////////////////////////////////////////////////////// +// nDetImplantOutputStructure +/////////////////////////////////////////////////////////// + +nDetImplantOutputStructure::nDetImplantOutputStructure(){ + nPhotonsTot = 0; + nPhotonsDet = 0; + lightBalance = 0; + tdiff = 0; + photonDetEff = 0; + barTOF = 0; + barQDC = 0; + barMaxADC = 0; + barTrig = false; + photonTOF = 0; + photonComX = 0; + photonComY = 0; + reconComX = 0; + reconComY = 0; + photonComCol = 0; + photonComRow = 0; +} + +void nDetImplantOutputStructure::SetValues(const unsigned int &nPhotonsTot_, const unsigned int &nPhotonsDet_, const double &lightBalance_, const double &tdiff_, const double &photonTdiff_, const double &photonDetEff_, const double &barTOF_, const double &barQDC_, const double &barMaxADC_, const bool &barTrig_, const double &photonTOF_, const double &photonComX_, const double &photonComY_, const double &reconComX_, const double &reconComY_, const short &photonComCol_, const short &photonComRow_){ + nPhotonsTot = nPhotonsTot_; + nPhotonsDet = nPhotonsDet_; + lightBalance = lightBalance_; + tdiff = tdiff_; + photonTdiff = photonTdiff_; + photonDetEff = photonDetEff_; + barTOF = barTOF_; + barQDC = barQDC_; + barMaxADC = barMaxADC_; + barTrig = barTrig_; + photonTOF = photonTOF_; + photonComX = photonComX_; + photonComY = photonComY_; + reconComX = reconComX_; + reconComY = reconComY_; + photonComCol = photonComCol_; + photonComRow = photonComRow_; +} + +void nDetImplantOutputStructure::Append(){ +} + +void nDetImplantOutputStructure::Zero(){ + nPhotonsTot = 0; + nPhotonsDet = 0; + lightBalance = 0; + tdiff = 0; + photonTdiff = 0; + photonDetEff = 0; + barTOF = 0; + barQDC = 0; + barMaxADC = 0; + barTrig = false; + photonTOF = 0; + photonComX = 0; + photonComY = 0; + reconComX = 0; + reconComY = 0; + photonComCol = 0; + photonComRow = 0; +} /////////////////////////////////////////////////////////// // nDetMultiOutputStructure @@ -184,6 +249,29 @@ void nDetMultiOutputStructure::Append(const nDetOutputStructure &output, const s multiplicity++; } +void nDetMultiOutputStructure::Append(const nDetImplantOutputStructure &output, const short &detID_){ + nPhotonsTot.push_back(output.nPhotonsTot); + nPhotonsDet.push_back(output.nPhotonsDet); + lightBalance.push_back(output.lightBalance); + tdiff.push_back(output.tdiff); + photonTdiff.push_back(output.photonTdiff); + photonDetEff.push_back(output.photonDetEff); + barTOF.push_back(output.barTOF); + barQDC.push_back(output.barQDC); + barMaxADC.push_back(output.barMaxADC); + barTrig.push_back(output.barTrig); + photonTOF.push_back(output.photonTOF); + photonComX.push_back(output.photonComX); + photonComY.push_back(output.photonComY); + reconComX.push_back(output.reconComX); + reconComY.push_back(output.reconComY); + photonComCol.push_back(output.photonComCol); + photonComRow.push_back(output.photonComRow); + detID.push_back(detID_); + multiplicity++; +} + + void nDetMultiOutputStructure::Append(const nDetDebugStructure &debug, const short nScatters_){ for(short iv=0; iv < nScatters_; iv++){ nScatterX.push_back(debug.nScatterX.at(iv)); diff --git a/include/centerOfMass.hh b/include/centerOfMass.hh index e275d0c..596a6ad 100644 --- a/include/centerOfMass.hh +++ b/include/centerOfMass.hh @@ -26,7 +26,7 @@ class centerOfMass{ public: /** Default constructor */ - centerOfMass() : Ncol(-1), Nrow(-1), Npts(0), NnotDetected(0), totalMass(0), t0(std::numeric_limits::max()), tSum(0), lambdaSum(0), + centerOfMass() : Ncol(1), Nrow(1), Npts(0), NnotDetected(0), totalMass(0), t0(std::numeric_limits::max()), tSum(0), lambdaSum(0), activeWidth(0), activeHeight(0), pixelWidth(0), pixelHeight(0), center(0, 0, 0), response() { } /** Destructor @@ -147,6 +147,14 @@ class centerOfMass{ /** Get the vertical photon center-of-mass position computed from the Anger Logic currents */ double getReconstructedY() const ; + + /** Get the horizontal photon center-of-mass position computed from the Sipm Logic + */ + double getSipmX() const ; + + /** Get the vertical photon center-of-mass position computed from the Sipm Logic + */ + double getSipmY() const ; /** Get the anode gain matrix */ diff --git a/include/nDetConstruction.hh b/include/nDetConstruction.hh index 1189fd8..4be2e0e 100644 --- a/include/nDetConstruction.hh +++ b/include/nDetConstruction.hh @@ -54,12 +54,19 @@ class nDetConstruction : public G4VUserDetectorConstruction{ */ G4VPhysicalVolume* ConstructDetector(); + /** Build the world volume and place all implants defined in the detector list + * @return A pointer to the world physical volume + */ + G4VPhysicalVolume* ConstructImplant(); + /** Add a detector geometry to the list of detectors * @note See nDetDetector::setGeometry() for accepted geometry names * @return True if the specified type is recognized and return false otherwise */ bool AddGeometry(const G4String &geom); + bool AddImplantGeometry(const G4String &geom); + /** Setup segmented PMTs */ void setSegmentedPmt(); @@ -92,6 +99,10 @@ class nDetConstruction : public G4VUserDetectorConstruction{ */ centerOfMass *GetCenterOfMassR(){ return ¢er[1]; } + /** Return a pointer to the optical photon center-of-mass calculator for the left PMT + */ + centerOfMass *GetCenterOfMass(){ return ¢er[0]; } //This is for the implant detector + /** Return a pointer to the PMT response for the left PMT */ pmtResponse *GetPmtResponseL(){ return center[0].getPmtResponse(); } @@ -100,10 +111,18 @@ class nDetConstruction : public G4VUserDetectorConstruction{ */ pmtResponse *GetPmtResponseR(){ return center[1].getPmtResponse(); } + /** Return a pointer to the PMT response for the left PMT + */ + pmtResponse *GetPmtResponse(){ return center[0].getPmtResponse(); } //This is for the implant detector + /** Get a copy of the current vector of detectors */ std::vector GetUserDetectors() const { return userDetectors; } + /** Get a copy of the current vector of implants + */ + std::vector GetUserImplants() const { return userImplants; } + /** Get the current user defined detector parameters */ nDetDetectorParams GetDetectorParameters() const { return params; } @@ -112,10 +131,18 @@ class nDetConstruction : public G4VUserDetectorConstruction{ */ nDetDetector *getCurrentDetector(){ return currentDetector; } + /** Get a pointer to the current detector + */ + nDetImplant *getCurrentImplant(){ return currentImplant; } + /** Clear all volumes, surfaces, and detectors */ void ClearGeometry(); + /** Clear all volumes, surfaces, and detectors + */ + void ClearImplantGeometry(); + /** Place all detectors into the world and copy the list of detectors to all user run actions */ void UpdateGeometry(); @@ -139,6 +166,8 @@ class nDetConstruction : public G4VUserDetectorConstruction{ * @note See nDetDetector::addLightGuideLayer(const G4String &) for input string syntax */ void AddLightGuide(const G4String &input); + + void AddSegmentedLightGuide(const G4String &input); /** Add an array of detectors in a cylindrical setup * @note String syntax:
@@ -152,6 +181,8 @@ class nDetConstruction : public G4VUserDetectorConstruction{ */ void AddDetectorArray(const G4String &input); + void AddImplantArray(const G4String &input); + /** Set the light yield multiplier for scintillator photon production * @param yield The fraction of the light yield to use for optical photon production in scintillators (default is 1) */ @@ -164,6 +195,10 @@ class nDetConstruction : public G4VUserDetectorConstruction{ /** Get clones of all currently defined detectors */ void GetCopiesOfDetectors(std::vector &detectors) const ; + + /** Get clones of all currently defined detectors + */ + void GetCopiesOfImplants(std::vector &implants) const ; /** Set the experimental setup name for construction */ @@ -177,8 +212,10 @@ class nDetConstruction : public G4VUserDetectorConstruction{ G4bool fCheckOverlaps; ///< Flag indicating that Geant should check for overlaps between all placed objects std::vector userDetectors; ///< Vector of all detectors added by the user + std::vector userImplants; ///< Vector of all implants added by the user nDetDetector *currentDetector; ///< Pointer to the current detector added by the user + nDetImplant *currentImplant; ///< Pointer to the current Implant added by the user centerOfMass center[2]; ///< Objects used to compute the detected optical photon center-of-mass position for the left and right PMT diff --git a/include/nDetDataPack.hh b/include/nDetDataPack.hh index cbd7bcb..f3afa85 100644 --- a/include/nDetDataPack.hh +++ b/include/nDetDataPack.hh @@ -17,16 +17,16 @@ class nDetDataPack{ public: /** Default constructor */ - nDetDataPack() : evtData(NULL), outData(NULL), multData(NULL), debugData(NULL), traceData(NULL) { } + nDetDataPack() : evtData(NULL), outData(NULL), outImplantData(NULL), multData(NULL), debugData(NULL), traceData(NULL) { } /** Data structure constructor */ - nDetDataPack(nDetEventStructure *evt, nDetOutputStructure *out, nDetMultiOutputStructure *mult, nDetDebugStructure *debug, nDetTraceStructure *trace) : - evtData(evt), outData(out), multData(mult), debugData(debug), traceData(trace) { } + nDetDataPack(nDetEventStructure *evt, nDetOutputStructure *out, nDetImplantOutputStructure *outImp, nDetMultiOutputStructure *mult, nDetDebugStructure *debug, nDetTraceStructure *trace) : + evtData(evt), outData(out), outImplantData(outImp), multData(mult), debugData(debug), traceData(trace) { } - void setDataAddresses(nDetEventStructure *evt, nDetOutputStructure *out, nDetMultiOutputStructure *mult, nDetDebugStructure *debug, nDetTraceStructure *trace); + void setDataAddresses(nDetEventStructure *evt, nDetOutputStructure *out, nDetImplantOutputStructure *outImp, nDetMultiOutputStructure *mult, nDetDebugStructure *debug, nDetTraceStructure *trace); - void copyData(nDetEventStructure *evt, nDetOutputStructure *out, nDetMultiOutputStructure *mult, nDetDebugStructure *debug, nDetTraceStructure *trace) const ; + void copyData(nDetEventStructure *evt, nDetOutputStructure *out, nDetImplantOutputStructure *outImp, nDetMultiOutputStructure *mult, nDetDebugStructure *debug, nDetTraceStructure *trace) const ; /** Return true if the current event is a good detection event, meaning that optical photons * were detected at the photo-sensitive surfaces of the detector, and return false otherwise @@ -44,6 +44,7 @@ class nDetDataPack{ private: nDetEventStructure *evtData; nDetOutputStructure *outData; + nDetImplantOutputStructure *outImplantData; nDetMultiOutputStructure *multData; nDetDebugStructure *debugData; nDetTraceStructure *traceData; diff --git a/include/nDetDetector.hh b/include/nDetDetector.hh index 214ba7e..50602dd 100644 --- a/include/nDetDetector.hh +++ b/include/nDetDetector.hh @@ -39,7 +39,7 @@ public: maxBodySize(30, 30, 600), scintMaterial(NULL), wrappingMaterial(NULL), wrappingOpSurf(NULL), scintVisAtt(NULL), wrappingVisAtt(NULL), - materials(NULL), fMessenger(NULL) { } + materials(NULL), fMessenger(NULL),dXseg(0),dYseg(0),dspacing(0.),dtopWidth(0.),dtopThick(0.),dbotWidth(0.),dbotThick(0.),dzThick(50.),dSegMaterial(""){ } /** Initialize the detector parameter messenger for this class * @note Since there may be multiple detectors in any given setup, the nDetDetectorMessenger class @@ -261,7 +261,21 @@ public: */ void Print() const ; + void setSegX(const G4int xseg){dXseg = xseg;} + void setSegY(const G4int yseg){dYseg = yseg;} + void setSegSpacing(const G4double spacing){dspacing = spacing;} + void setSegTopWidth(const G4double topWidth){dtopWidth = topWidth;} + void setSegTopThick(const G4double topThick){dtopThick = topThick;} + void setSegBotWidth(const G4double botWidth){dbotWidth = botWidth;} + void setSegBotThick(const G4double botThick){dbotThick = botThick;} + void setSegZThick(const G4double zThick){dzThick = zThick;} + void setSegMaterial(const G4String mat){dSegMaterial = mat;} + + void setReconLogic(const bool logic=0){reconLogic=logic;} + bool GetReconLogic(){return reconLogic;} + protected: + bool reconLogic; ///< Setting whether to use the sipmLogic (1) or pspmt logic (0) G4double pmtWidth; ///< The width (x-axis) of the PMT (in mm) G4double pmtHeight; ///< The height (y-axis) of the PMT (in mm) G4double fWrappingThickness; ///< Thickness of the inner and outer detector wrapping (in mm) @@ -303,16 +317,32 @@ protected: G4Material* scintMaterial; ///< Pointer to the detector scintillator material G4Material* wrappingMaterial; ///< Pointer to the detector wrapping material + G4Material* outerMylar; ///< Pointer to mylar for outer wrapping G4OpticalSurface* wrappingOpSurf; ///< Pointer to the wrapping optical surface + G4OpticalSurface* wrappingOuterOpSurf; ///< Pointer to the outer wrapping optical surface G4VisAttributes* scintVisAtt; ///< Pointer to the detector scintillator visual attributes G4VisAttributes* wrappingVisAtt; ///< Pointer to the detector wrapping visual attributes + G4VisAttributes* windowVisAtt; ///< Pointer to the detector window visual attributes nDetMaterials *materials; ///< Pointer to the NEXTSim Geant materials container nDetDetectorMessenger *fMessenger; ///< Geant messenger to use for this class + ////// + //These variables are for a segmented light guide + ////// + G4int dXseg; + G4int dYseg; + G4double dspacing; + G4double dtopWidth; + G4double dtopThick; + G4double dbotWidth; + G4double dbotThick; + G4double dzThick; + G4String dSegMaterial; + /** Update the size of the detector */ void UpdateSize(); @@ -703,4 +733,391 @@ protected: G4CSGSolid *getLightGuideVolume(const G4String &name, const G4double &w1, const double &w2, const double &h1, const double &h2, const G4double &length); }; +/** @class nDetImplant + * @brief An individual implant assembly + * @author Ian Cox (icox2@vols.utk.edu) + * @date July 2020 + */ + +class nDetImplant : public nDetDetectorParams { +public: + /** Default constructor + */ + nDetImplant() : nDetDetectorParams(), + assembly_logV(NULL), assembly_physV(NULL), layerSizeX(0), layerSizeY(0), offsetZ(0), + parentCopyNum(0), firstSegmentCopyNum(0), lastSegmentCopyNum(0), + checkOverlaps(false) { } + + /** Detector parameter copier constructor + */ + nDetImplant(const nDetDetectorParams* params) : nDetDetectorParams((*params)), + assembly_logV(NULL), assembly_physV(NULL), layerSizeX(0), layerSizeY(0), offsetZ(0), + parentCopyNum(0), firstSegmentCopyNum(0), lastSegmentCopyNum(0), + checkOverlaps(false) { } + + /** Detector constructor + * @param detector Pointer to a nDetConstruction object where the current detector is defined + * @param matptr Pointer to the Geant materials handler class which will be used for detector construction + */ + nDetImplant(nDetConstruction *detector, nDetMaterials *matptr); + + /** Destructor + */ + virtual ~nDetImplant(); + + /** Clone this detector + * @return A new copy of this detector instance + */ + nDetImplant clone() const ; + + /** Get a pointer to the logical volume of the detector assembly + */ + G4LogicalVolume *getLogicalVolume(){ return assembly_logV; } + + /** Get the width and height of the current layer as well as the current offset along the detector length + * @param x_ Width of the current layer (in mm) + * @param y_ Height of the current layer (in mm) + * @param z_ Offset along the detector length (in mm) + */ + void getCurrentOffset(G4double &x_, G4double &y_, G4double &z_); + + /** Get the copy number of this detector (i.e. the detector ID) + */ + G4int getParentCopyNumber() const { return parentCopyNum; } + + /** Get the copy number of the left PMT + */ + G4int getPmtCopyNumber() const { return 2*parentCopyNum; } + + /** Get a pointer to the vector representing the central position of this detector + */ + G4ThreeVector *getPosition(){ return &detectorPosition; } + + /** Get a pointer to the rotation matrix used for this detector + */ + G4RotationMatrix *getRotation(){ return &detectorRotation; } + + /** Enable or disable checking overlaps with existing geometry when placing objects + */ + void setCheckOverlaps(const bool &enabled){ checkOverlaps = enabled; } + + /** Set the position and the rotation of this detector + * @param pos The position of the center of the detector (in mm) + * @param rot The rotation matrix + */ + void setPositionAndRotation(const G4ThreeVector &pos, const G4RotationMatrix &rot); + + /** Set the width and height of the current layer as well as the current offset along the detector length + * @param x_ Width of the current layer (in mm) + * @param y_ Height of the current layer (in mm) + * @param z_ Offset along the detector length (in mm) + */ + void setCurrentOffset(const G4double &x_, const G4double &y_, const G4double &z_); + + /** Current offset along the detector length (Z-axis, in mm) + */ + void setCurrentOffsetZ(const G4double &z_){ offsetZ = z_; } + + /** Set the copy number of this detector (i.e. the detector ID) + */ + void setParentCopyNumber(const G4int &num){ parentCopyNum = num; } + + /** Build the detector body, add component layers, and attach photo-sensitive surfaces + */ + void construct(); + + /** Add a user defined layer to the queue + * @note When buildAllLayers() is called, the layers will be added on a first-in-first-out basis + */ + void addLayer(nDetWorldObject *layer){ userLayers.push_back(layer); } + + /** Add all layers added by addLayer() to the detector construction + */ + void buildAllLayers(); + + /** Place this detector assembly into a parent logical volume + * @param Pointer to the logical volume of the parent assembly + */ + void placeImplant(G4LogicalVolume *parent); + + /** Clear both the left and right photon center-of-mass calculators + */ + void clear(); + + /** Copy the center-of-mass calculator for the left and right PMTs + * @param left Left PMT center-of-mass calculator + * @param right Right PMT center-of-mass calculator + */ + void copyCenterOfMass(const centerOfMass &implant); //This might need to be dealt with + + /** Check if a scintillator copy number is part of this detector + * @param num The copy number of a scintillator segment + * @return True if the copy number is part of this detector and return false otherwise + */ + bool checkCopyNumber(const G4int &num) const { return (num >= firstSegmentCopyNum && num < lastSegmentCopyNum); } + + /** Check if a PMT copy number is part of this detector + * @param num The copy number of a scintillator segment + * @return True if the copy number is part of this detector and return false otherwise + */ + bool checkPmtCopyNumber(const G4int &num) const { return (num == 2*parentCopyNum || num == 2*parentCopyNum+1); } + + /** Check if a PMT copy number is part of this detector + * @param num The copy number of a scintillator segment + * @param isLeft Returned flag indicating that the copy number refers to the left PMT + * @return True if the copy number is part of this detector and return false otherwise + */ + bool checkPmtCopyNumber(const G4int &num, bool &isLeft) const ; //I believe this is unneeded + + /** Get the column and row corresponding to a segment copy number in a segmented detector + * @param copyNum The copy number of a scintillator segment + * @param col The segmented detector column corresponding to the copy number + * @param row The segmented detector row corresponding to the copy number + * @return True if the copy number is found to be part of a detector and return false otherwise + */ + bool getSegmentFromCopyNum(const G4int ©Num, G4int &col, G4int &row) const ; + + /** Retrun true if both the left and right photon center-of-mass calculators are empty and return false otherwise + */ + bool empty() const { return (cmI.empty()); } + + /** Return a pointer to the optical photon center-of-mass calculator for the Implant PMT + */ + centerOfMass *getCenterOfMass(){ return &cmI; } //Adjusted for 1 pspmt + + /** Return a pointer to the PMT response for the Implant PMT + */ + pmtResponse *getPmtResponse(){ return cmI.getPmtResponse(); } + + /** Load a light guide model from a file using parameters from a space-delimited input string and place it into the current detector assembly + * @note See gdmlLightGuideLayer::decodeString() for input string syntax + */ + void addLightGuideGDML(const G4String &input); + + /** Apply a grease layer to the current detector assembly using dimensions from a space-delimited input string + * @note See greaseLayer::decodeString() for input string syntax + */ + void addGreaseLayer(const G4String &input); + + /** Apply a straight light diffuser layer (quartz) to the current detector assembly using dimensions from a space-delimited input string + * @note See diffuserLayer::decodeString() for input string syntax + */ + void addDiffuserLayer(const G4String &input); + + /** Apply a trapezoidal light guide layer (quartz) to the current detector assembly using dimensions from a space-delimited input string + * @note See lightGuideLayer::decodeString() for input string syntax + */ + void addLightGuideLayer(const G4String &input); + + /** Apply a segmented light guide which can be tapered to implant detector assembly + * @note use messenger to set various parameters + */ + void addSegmentedLightGuideLayer(const G4String &input); + + /** Build the assembly volume for the current detector + * @param boundingBox The returned X, Y, and Z size of the assembly volume for the current detector + * @return A pointer to the logical volume of the assembly of the current detector + */ + //Here there might need to be an implementation of the front face mylar/esr + G4LogicalVolume *constructAssembly(); + + /** Add a daughter to the logical volume of the detector body + * @param volume Pointer to the logical volume to add to the detector body + * @param name The name of the new physical volume. If the name is blank, the name of the input logical volume will be used + * @param pos The X, Y, and Z position offset of the daughter within the detector body (all in mm) + * @param rot Pointer to the rotation matrix of the daughter within the detector body + * @return A pointer to the physical volume of the daughter + */ + G4PVPlacement *addToDetectorBody(G4LogicalVolume *volume, const G4String &name="", const G4ThreeVector &pos=G4ThreeVector(0,0,0), G4RotationMatrix *rot=NULL); + + /** Add a particle-sensitive daughter to the logical volume of the detector body + * @note The copy number of the new physical volume will be automatically set by this method + * @param volume Pointer to the logical volume to add to the detector body + * @param name The name of the new physical volume. If the name is blank, the name of the input logical volume will be used + * @param pos The X, Y, and Z position offset of the daughter within the detector body (all in mm) + * @param rot Pointer to the rotation matrix of the daughter within the detector body + * @return A pointer to the physical volume of the daughter + */ + G4PVPlacement *addSegmentToBody(G4LogicalVolume *volume, const G4String &name="", const G4ThreeVector &pos=G4ThreeVector(0,0,0), G4RotationMatrix *rot=NULL); + + /** Add a logical volume to the (-z) of the detector assembly + * @param volume Pointer to the logical volume to add to the detector body + * @param offset The position offset along the length axis of the detector (in mm) + * @param name The name of the new physical volume. If the name is blank, the name of the input logical volume will be used + * @param rot Pointer to the rotation matrix of the daughter within the detector body + * @return A pointer to the physical volume of the daughter + */ + G4PVPlacement *addFrontComponent(G4LogicalVolume *volume, const G4double &offset, const G4String &name="", G4RotationMatrix *rot=NULL); + + void addFrontComponent(G4PVPlacement* &phys1, G4LogicalVolume *volume, const G4double &offset, const G4String &name/*=""*/, G4RotationMatrix *rot/*=NULL*/); + + /** Add a logical volume to the (+z) of the detector assembly + * @param volume Pointer to the logical volume to add to the detector body + * @param offset The position offset along the length axis of the detector (in mm) + * @param name The name of the new physical volume. If the name is blank, the name of the input logical volume will be used + * @param rot Pointer to the rotation matrix of the daughter within the detector body + * @return A pointer to the physical volume of the daughter + */ + G4PVPlacement *addBackComponent(G4LogicalVolume *volume, const G4double &offset, const G4String &name="", G4RotationMatrix *rot=NULL); + + void addBackComponent(G4PVPlacement* &phys1, G4LogicalVolume *volume, const G4double &offset, const G4String &name/*=""*/, G4RotationMatrix *rot/*=NULL*/); + + /** Add a logical volume to both the left and right sides of the detector assembly + * @note This method assumes that the input volume is symmetric about the z-axis and, thus, it is + * not rotated when being placed on the opposite side of the detector assembly + * @param volume Pointer to the logical volume to add to the detector body + * @param offset The position offset along the length axis of the detector (in mm) + * @param name The name of the new physical volume. If the name is blank, the name of the input logical volume will be used + * @param rot Pointer to the rotation matrix of the daughter within the detector body + */ + void addMirroredComponents(G4LogicalVolume *volume, const G4double &offset, const G4String &name="", G4RotationMatrix *rot=NULL); + + /** Add a logical volume to both the left and right sides of the detector assembly and return their physical volumes + * @note This method assumes that the input volume is symmetric about the z-axis and, thus, it is + * not rotated when being placed on the opposite side of the detector assembly + * @param phys1 Returned pointer to the physical volume of the left component + * @param phys2 Returned pointer to the physical volume of the right component + * @param volume Pointer to the logical volume to add to the detector body + * @param offset The position offset along the length axis of the detector (in mm) + * @param name The name of the new physical volume. If the name is blank, the name of the input logical volume will be used + * @param rot Pointer to the rotation matrix of the daughter within the detector body + */ + void addMirroredComponents(G4PVPlacement* &phys1, G4PVPlacement* &phys2, G4LogicalVolume *volume, const G4double &offset, const G4String &name="", G4RotationMatrix *rot=NULL); + + /** Apply a grease layer to the current detector assembly using the current detector width and height + */ + void applyGreaseLayer(); + + /** Apply a grease layer to the current detector assembly + * @param x The width of the grease layer (in mm) + * @param y The height of the grease layer (in mm) + * @param thickness The thickness of the grease layer (in mm). If not specified, @a fGreaseThickness is used + */ + void applyGreaseLayer(const G4double &x, const G4double &y, double thickness=0); + + /** Apply a straight light diffuser layer (quartz) to the current detector assembly using the current detector width and height + */ + void applyDiffuserLayer(); + + /** Apply a straight light diffuser layer (quartz) to the current detector assembly + * @param x The width of the diffuser layer (in mm) + * @param y The height of the diffuser layer (in mm) + * @param thickness The thickness of the diffuser layer (in mm) + */ + void applyDiffuserLayer(const G4double &x, const G4double &y, const double &thickness); + + /** Apply a trapezoidal light guide layer (quartz) to the current detector assembly reducing the current detector width and height + * down to the width and height of the PMT + */ + void applyLightGuide(); + + /** Apply a trapezoidal light guide layer (quartz) to the current detector assembly reducing the current detector width and height + * down to a user specified width and height + * @param x2 The width of the small side of the trapezoid (in mm) + * @param y2 The height of the amll side of the trapezoid (in mm) + */ + void applyLightGuide(const G4double &x2, const G4double &y2); + + /** Apply a trapezoidal light guide layer (quartz) to the current detector assembly + * @param x1 The width of the large side of the trapezoid (in mm) + * @param x2 The width of the small side of the trapezoid (in mm) + * @param y1 The height of the large side of the trapezoid (in mm) + * @param y2 The height of the amll side of the trapezoid (in mm) + * @param thickness The thickness of the light guide (in mm) + */ + void applyLightGuide(const G4double &x1, const G4double &x2, const G4double &y1, const G4double &y2, const double &thickness); + + /** Load a GDML model from a file and place it into the assembly + * @param solid Pointer to a gdml model loaded from a file + */ + void loadGDML(gdmlSolid *solid); + + /** Load a GDML light guide model from a file and place it into the assembly + * + * This method performs the same as loadGDML() except that it also defines logical border surfaces on all intersecting faces + * + * @param solid Pointer to a gdml model loaded from a file + * @param rotation Rotation of the gdml model about the X, Y, and Z axes (all in radians) + */ + void loadLightGuide(gdmlSolid *solid, const G4ThreeVector &rotation); + + void applySegmentedLightGuide(G4int Xseg, G4int Yseg, G4double spacing, G4double topWidth, G4double topThick, G4double botWidth, G4double botThick, G4double zThick); + +protected: + bool sipmLogic; ///< Setting whether to use the sipmLogic (1) or pspmt logic (0) + G4LogicalVolume *assembly_logV; ///< Pointer to the logical volume of the mother of the detector + G4PVPlacement* assembly_physV; ///< Pointer to the physical volume of the mother of the detector + + G4double layerSizeX; ///< Width of the current user add layer (in mm) + G4double layerSizeY; ///< Height of the current user add layer (in mm) + G4double offsetZ; ///< Offset of the current user add layer along the z-axis (in mm) + + G4int parentCopyNum; ///< Copy number of the mother of the detector + G4int firstSegmentCopyNum; ///< Copy number of the first scintillator segment + G4int lastSegmentCopyNum; ///< Copy number of the last scintillator segment + + bool checkOverlaps; ///< Flag indicating that Geant should check for overlaps between all placed objects + + centerOfMass cmI; ///< Center-of-mass calculator for the PMT + + std::vector userLayers; ///< Vector of all layers added by the user + + std::vector scintBody_physV; ///< Vector of all physical volumes of all scintillator segments + + /** Prepare for the detector volume to be built. In this method, the user should set the maximum + * size constraints of the body of the detector (@a maxBodySize) so that the detector handler knows + * how large to make its bounding assembly volume. + * @note By default, the maximum body size is taken from @a fDetectorWidth, @a fDetectorHeight, and @a fDetectorLength + */ + virtual void prepareToBuild(); + + /** Build the physical detector volume for the detector handler + */ + virtual void buildDetector(){ } + + /** Perform tasks after the detector assembly has been placed into the setup area + */ + virtual void afterPlacement(){ } + + /** Handle cloning of derived classes + * @note Should usually do nothing, but the derived class may need to modify some nDetDetector members + */ + virtual void cloneChild(nDetDetector &) const { } + + /** Build PMTs for the current detector and place them in the assembly volume + * + * Each PMT consists of an optical grease layer, a quartz window, and a photo-sensitive surface. Additionally, + * a reflective wrapping layer is added around the outside of the PMT if @a fWrappingThickness is greater than zero. + */ + void constructPSPmt(); //this has been changed for singular pspmt + + /** Return a geometric solid volume with a specified size + * + * If the class member @a fSquarePMTs is true, then a G4Box is returned, otherwise a G4Tubs is returned + * @note All size parameters are specified as the TOTAL size and not the half-size as with most Geant geometry methods + * @param name The name of the new geometric solid + * @param width The total size along the X-axis (in mm) + * @param height The total size along the Y-axis (in mm) + * @param length The total size along the Z-axis (in mm) + * @return A pointer to the new G4CSGSolid (Constructed Solid Geometry) volume + */ + G4CSGSolid *getVolume(const G4String &name, const G4double &width, const G4double &height, const G4double &length); + + /** Return a geometric solid trapezoid or cone with a specified size + * + * If the class member @a fSquarePMTs is true, then a G4Trd is returned, otherwise a G4Cons is returned + * @note All size parameters are specified as the TOTAL size and not the half-size as with most Geant geometry methods + * @param name The name of the new geometric solid + * @param w1 The total size along the X-axis at z = -length/2 (in mm) + * @param w2 The total size along the X-axis at z = +length/2 (in mm) + * @param h1 The total size along the Y-axis at z = -length/2 (in mm) + * @param h2 The total size along the Y-axis at z = +length/2 (in mm) + * @param length The total size along the Z-axis (in mm) + * @return A pointer to the new G4CSGSolid (Constructed Solid Geometry) volume + */ + G4CSGSolid *getLightGuideVolume(const G4String &name, const G4double &w1, const double &w2, const double &h1, const double &h2, const G4double &length); + +}; + + #endif diff --git a/include/nDetDetectorLayer.hh b/include/nDetDetectorLayer.hh index c36972f..d0acc4c 100644 --- a/include/nDetDetectorLayer.hh +++ b/include/nDetDetectorLayer.hh @@ -9,6 +9,7 @@ #include "nDetWorldObject.hh" class nDetDetector; +class nDetImplant; /** @class greaseLayer * @brief Optical grease component layer which is added to a detector assembly @@ -42,6 +43,8 @@ class greaseLayer : public nDetWorldObject { */ virtual void construct(nDetDetector *obj); + virtual void construct(nDetImplant *obj); + /** Return a string containing proper input string syntax */ virtual std::string syntaxStr() const ; @@ -89,6 +92,8 @@ class diffuserLayer : public nDetWorldObject { */ virtual void construct(nDetDetector *obj); + virtual void construct(nDetImplant *obj); + /** Return a string containing proper input string syntax */ virtual std::string syntaxStr() const ; @@ -118,7 +123,7 @@ class lightGuideLayer : public nDetWorldObject { /** Destructor */ - lightGuideLayer(){ } + ~lightGuideLayer(){ } /** Apply a trapezoidal light guide layer (quartz) to the current detector assembly using dimensions from a space-delimited input string * @note String syntax: [material=G4_SILICON_DIOXIDE] @@ -138,6 +143,8 @@ class lightGuideLayer : public nDetWorldObject { */ virtual void construct(nDetDetector *obj); + virtual void construct(nDetImplant *obj); + /** Return a string containing proper input string syntax */ virtual std::string syntaxStr() const ; @@ -154,6 +161,28 @@ class lightGuideLayer : public nDetWorldObject { G4double thickness; ///< Thickness of the trapezoid (in mm) }; +class segLightGuideLayer : public nDetWorldObject { + public: + segLightGuideLayer(const G4String &arg_); + ~segLightGuideLayer(); + + virtual bool decodeArgs(); + virtual void construct(nDetDetector *obj); + virtual void construct(nDetImplant *obj); + virtual std::string syntaxStr() const; + virtual void placeObject(G4LogicalVolume*, nDetMaterials*) {} + private: + G4int fXseg; + G4int fYseg; + G4double fspacing; + G4double ftopWidth; + G4double ftopThick; + G4double fbotWidth; + G4double fbotThick; + G4double fzThick; + G4String fSegMaterial; +}; + /** @class gdmlLightGuideLayer * @brief GDML model component which is added to a detector assembly * @author Cory R. Thornsberry (cthornsb@vols.utk.edu) @@ -191,6 +220,8 @@ class gdmlLightGuideLayer : public nDetWorldObject { */ virtual void construct(nDetDetector *obj); + virtual void construct(nDetImplant *obj); + /** Return a string containing proper input string syntax */ virtual std::string syntaxStr() const ; diff --git a/include/nDetDetectorTypes.hh b/include/nDetDetectorTypes.hh index 02c7d69..3662b1f 100644 --- a/include/nDetDetectorTypes.hh +++ b/include/nDetDetectorTypes.hh @@ -22,6 +22,7 @@ namespace nDetDetectorTypes{ * @return A pointer to the new nDetDetector instance */ nDetDetector* getDetectorType(const G4String &geom); +nDetImplant* getImplantType(const G4String &geom); /** Get a pointer to a new detector * @param geom The name of the detector type @@ -30,6 +31,7 @@ nDetDetector* getDetectorType(const G4String &geom); * @return A pointer to the new nDetDetector instance */ nDetDetector* getDetectorType(const G4String &geom, nDetConstruction *detector, nDetMaterials *matptr); +nDetImplant* getImplantType(const G4String &geom, nDetConstruction *detector, nDetMaterials *matptr); /** @class nextModuleType * @author Cory R. Thornsberry (cthornsb@vols.utk.edu) @@ -181,6 +183,78 @@ public: protected: }; + +class implantType : public nDetImplant { +public: + /** Default constructor + */ + implantType() : nDetImplant() { } + + /** Detector constructor + * @param detector Pointer to a nDetConstruction object where the current detector is defined + * @param matptr Pointer to the Geant materials handler class which will be used for detector construction + */ + implantType(nDetConstruction *detector, nDetMaterials *matptr) : nDetImplant(detector, matptr) { } + + /** Destructor + */ + ~implantType(){ } + + /** Prepare for the detector volume to be built. In this method, the user should set the maximum + * size constraints of the body of the detector so that the detector handler knows how large to + * make its bounding assembly volume. + */ + virtual void prepareToBuild(); + + /** Build a segmented detector module + * + * The detector will have @a fNumColumns columns (horizontal) and @a fNumRows rows (vertical). If @a fWrappingThickness is + * greater than zero, the user selected wrapping material will be applied between all segments and around the outside + * of the detector. + */ + virtual void buildDetector(); + +protected: +}; + +/** @class hagridType + * @author Cory R. Thornsberry (cthornsb@vols.utk.edu) + * @date September 25, 2019 + * @brief Single-segment cylindrical detectector + */ + +class hagridType : public nDetImplant { +public: + /** Default constructor + */ + hagridType() : nDetImplant() { } + + /** Detector constructor + * @param detector Pointer to a nDetConstruction object where the current detector is defined + * @param matptr Pointer to the Geant materials handler class which will be used for detector construction + */ + hagridType(nDetConstruction *detector, nDetMaterials *matptr) : nDetImplant(detector, matptr) { } + + /** Destructor + */ + ~hagridType(){ } + + /** Prepare for the detector volume to be built. In this method, the user should set the maximum + * size constraints of the body of the detector so that the detector handler knows how large to + * make its bounding assembly volume. + */ + virtual void prepareToBuild(); + + /** Build a single-segment cylindrical detectector + * + * The parameter @a fDetectorWidth is used as the diameter of the cylindrical body, @a fDetectorheight is not used + */ + virtual void buildDetector(); + +protected: +}; + + } // namespace nDetDetectorTypes #endif diff --git a/include/nDetMasterOutputFile.hh b/include/nDetMasterOutputFile.hh index 8fadb4b..1473307 100644 --- a/include/nDetMasterOutputFile.hh +++ b/include/nDetMasterOutputFile.hh @@ -156,6 +156,7 @@ class nDetMasterOutputFile{ TFile *fFile; ///< Pointer to the output root file TTree *fTree; ///< Pointer to the output TTree + TTree *fImpTree; ///< Pointer to the output TTree bool persistentMode; ///< Flag indicating whether or not the output file should remain open for subsequent runs bool verbose; ///< Verbosity flag @@ -169,6 +170,7 @@ class nDetMasterOutputFile{ nDetEventStructure *evtData; ///< Pointer to data structure containing Geant4 event information nDetOutputStructure *outData; ///< Pointer to data structure containing normal (single-detector) output variables + nDetImplantOutputStructure *outImplantData; ///< Pointer to data structure containing normal (single-detector) output variables nDetMultiOutputStructure *multData; ///< Pointer to data structure containing multi-detector output variables nDetDebugStructure *debugData; ///< Pointer to data structure containing debug output variables nDetTraceStructure *traceData; ///< Pointer to data structure containing PMT response light pulses diff --git a/include/nDetMaterials.hh b/include/nDetMaterials.hh index 19ecac0..c24bb8f 100644 --- a/include/nDetMaterials.hh +++ b/include/nDetMaterials.hh @@ -32,6 +32,11 @@ class nDetMaterials{ G4Element* fF; ///< Flourine G4Element* fSi; ///< Silicon G4Element* fAl; ///< Aluminium + G4Element* fY; ///< Yttrium + G4Element* fLa; ///< Lanthinum + G4Element* fBr; ///< Bromine + G4Element* fGd; ///< Gadolinium + G4Element* fGa; ///< Gallium G4Material* fAir; ///< Material corresponding to air G4Material* fVacuum; ///< Material corresponding to natural vacuum @@ -43,37 +48,48 @@ class nDetMaterials{ G4Material* fSilicon; ///< Material corresponding to silicon G4Material* fMylar; ///< Material corresponding to aluminized mylar G4Material* fAcrylic; ///< Material corresponding to acrylic - G4Material* fAluminum; ///< Material corresponding to aluminum + G4Material* fAluminum; ///< Material corresponding to aluminum + G4Material* fYSO; ///< Material corresponding to yttrium orthosilicate + G4Material* fYAP; ///< yttrium aluminum perovskite + G4Material* fGAGG; ///< Gadolinium Aluminum Gallium Garnet (Gd3Al2Ga3O12) + G4Material* fLaBr3; ///< Lanthinum Bromide + // Material table properties G4MaterialPropertiesTable* fAirMPT; ///< Material properties table for air G4MaterialPropertiesTable* fTeflonMPT; ///< Material properties table for teflon G4MaterialPropertiesTable* fEJ200MPT; ///< Material properties table for EJ-200 scintillator G4MaterialPropertiesTable* fEJ276MPT; ///< Material properties table for EJ-276 scintillator + G4MaterialPropertiesTable* fYSOMPT; ///< Material properties table for YSO scintillator + G4MaterialPropertiesTable* fYAPMPT; ///< MPT for YAP scintillator + G4MaterialPropertiesTable* fGAGGMPT; ///< MPT for GAGG scintillator + G4MaterialPropertiesTable* fLaBr3MPT; ///< MPT for LaBr3 scintillator G4MaterialPropertiesTable* fGreaseMPT; ///< Material properties table for optical grease G4MaterialPropertiesTable* fSiO2MPT; ///< Material properties table for quartz G4MaterialPropertiesTable* fSiliconMPT; ///< Material properties table for silicon - G4MaterialPropertiesTable* fMylarMPT; ///< Material properties table for aluminized mylar - G4MaterialPropertiesTable* fPerfectMPT; ///< Material properties table for a perfect reflector - G4MaterialPropertiesTable* fAluminumMPT; ///< Material properties table for aluminum - G4MaterialPropertiesTable* fEsrMPT; ///< Material properties table for 3M Enhanced Specular Reflector + G4MaterialPropertiesTable* fMylarMPT; ///< Material properties table for aluminized mylar + G4MaterialPropertiesTable* fPerfectMPT; ///< Material properties table for a perfect reflector + G4MaterialPropertiesTable* fAluminumMPT; ///< Material properties table for aluminum + G4MaterialPropertiesTable* fEsrMPT; ///< Material properties table for 3M Enhanced Specular Reflector // Optical Surfaces G4OpticalSurface* fTeflonOpSurf; ///< Optical surface for teflon G4OpticalSurface* fSiliconOpSurf; ///< Optical surface for silicon G4OpticalSurface* fMylarOpSurf; ///< Optical surface for aluminized mylar G4OpticalSurface* fEsrOpSurf; ///< Optical surface for 3M Enhanced Specular Reflector - G4OpticalSurface* fPerfectOpSurf; ///< Optical surface for a perfect reflector - G4OpticalSurface* fGreaseOpSurf; ///< Optical surface for optical grease - - // Visual attributes - G4VisAttributes *visAssembly; ///< Visual attributes for the mother assembly - G4VisAttributes *visSensitive; ///< Visual attributes for the photo-sensitive surface - G4VisAttributes *visWindow; ///< Visual attributes for the optical window - G4VisAttributes *visGrease; ///< Visual attributes for the optical grease - G4VisAttributes *visWrapping; ///< Visual attributes for the inner/outer detector wrappint - G4VisAttributes *visScint; ///< Visual attributes for the scintillator material - G4VisAttributes *visShadow; ///< Visual attributes for the shadow object + G4OpticalSurface* fPerfectOpSurf; ///< Optical surface for a perfect reflector + G4OpticalSurface* fGreaseOpSurf; ///< Optical surface for optical grease + G4OpticalSurface* fAirOpSurf; ///< Optical surface for air + G4OpticalSurface* fAluminumOpSurf; ///< Optical surface for aluminum + + // Visual attributes + G4VisAttributes *visAssembly; ///< Visual attributes for the mother assembly + G4VisAttributes *visSensitive; ///< Visual attributes for the photo-sensitive surface + G4VisAttributes *visWindow; ///< Visual attributes for the optical window + G4VisAttributes *visGrease; ///< Visual attributes for the optical grease + G4VisAttributes *visWrapping; ///< Visual attributes for the inner/outer detector wrappint + G4VisAttributes *visScint; ///< Visual attributes for the scintillator material + G4VisAttributes *visShadow; ///< Visual attributes for the shadow object /** Default constructor */ diff --git a/include/nDetParticleSource.hh b/include/nDetParticleSource.hh index 170658c..4a58c04 100644 --- a/include/nDetParticleSource.hh +++ b/include/nDetParticleSource.hh @@ -16,10 +16,13 @@ class G4ParticleDefinition; class G4Event; class nDetParticleSource; +//class nDetImplantParticleSource; class Reaction; class nDetParticleSourceMessenger; +//class nDetImplantParticleSourceMessenger; class nDetDetector; +class nDetImplant; /** @class nDetParticleSource * @brief Wrapper of G4GeneralParticleSource class for added convenience @@ -51,7 +54,7 @@ class nDetParticleSource : public G4GeneralParticleSource { /** Get an instance of the singleton */ static nDetParticleSource &getInstance(); - + /** Get a pointer to the messenger used for this class */ nDetParticleSourceMessenger *GetMessenger(){ return fSourceMessenger; } @@ -146,6 +149,11 @@ class nDetParticleSource : public G4GeneralParticleSource { */ void SetDetector(const nDetDetector *det); + /** Set information about the size and position of the detector for isotropic sources + * @param det Pointer to the detector + */ + void SetImplant(const nDetImplant *imp); + /** Set the source isotropy mode * @note 0=off, 1=psuedo, 2=realistic * @param mode The isotropy mode of the source @@ -188,6 +196,17 @@ class nDetParticleSource : public G4GeneralParticleSource { */ void SetNeutronBeam(const double &energy_); + /** Set a beam of mono-energetic alphas + * @param energy_ Energy of the beam (in MeV) + */ + void SetAlphaBeam(const double &energy_); + + /** Set a beam of mono-energetic ions + * @param energy_ Energy of the beam (in MeV) + */ + void SetIonBeam(const double &energy_, const int &A, const int &Z, const double &exE=0); + //void SetIonBeam(const G4String &str); + /** Set a beam of mono-energetic gamma-rays * @param energy_ Energy of the beam (in MeV) */ @@ -319,7 +338,7 @@ class nDetParticleSource : public G4GeneralParticleSource { /** Default constructor (private for singleton class) */ - nDetParticleSource(nDetDetector *det=NULL); + nDetParticleSource(nDetDetector *det=NULL, nDetImplant *imp=NULL); /** Get the next G4SingleParticleSource in the vector of all sources * @return A pointer to the next source (starting from the zeroth) or return NULL if the end of the vector has been reached @@ -390,6 +409,7 @@ class nDetPrimaryGeneratorAction : public G4VUserPrimaryGeneratorAction{ private: nDetParticleSource *source; ///< Pointer to the primary particle generator singleton + //DetImplantParticleSource *sourceImp; ///< Pointer to the primary particle generator singleton }; -#endif +#endif \ No newline at end of file diff --git a/include/nDetRunAction.hh b/include/nDetRunAction.hh index 775b699..068b09b 100644 --- a/include/nDetRunAction.hh +++ b/include/nDetRunAction.hh @@ -21,6 +21,7 @@ class nDetTrackingAction; class nDetSteppingAction; class nDetConstruction; class pmtResponse; +class nDetDetectorParams; class photonCounter; class nDetParticleSource; @@ -174,6 +175,12 @@ class nDetRunAction : public G4UserRunAction */ pmtResponse *getPmtResponseRight(const size_t &index=0){ return (index < userDetectors.size() ? userDetectors.at(index).getCenterOfMassR()->getPmtResponse() : NULL); } + /** Get a pointer to the left PMT dynode response object of one of the defined detectors + * @param index The index of the detector in the list of defined detectors + * @return The pointer to the dynode response if @a index corresponds to a defined detector and return NULL otherwise + */ + pmtResponse *getPmtResponseImplant(const size_t &index=0){ return (index < userImplants.size() ? userImplants.at(index).getCenterOfMass()->getPmtResponse() : NULL); } + /** Get a pointer to the array of left PMT anode response objects of one of the defined detectors * @param index The index of the detector in the list of defined detectors * @return The pointer to the array of anode responses if @a index corresponds to a defined detector and return NULL otherwise @@ -186,6 +193,12 @@ class nDetRunAction : public G4UserRunAction */ pmtResponse *getAnodeResponseRight(const size_t &index=0){ return (index < userDetectors.size() ? userDetectors.at(index).getCenterOfMassR()->getAnodeResponse() : NULL); } + /** Get a pointer to the array of left PMT anode response objects of one of the defined detectors + * @param index The index of the detector in the list of defined detectors + * @return The pointer to the array of anode responses if @a index corresponds to a defined detector and return NULL otherwise + */ + pmtResponse *getAnodeResponseImplant(const size_t &index=0){ return (index < userImplants.size() ? userImplants.at(index).getCenterOfMass()->getAnodeResponse() : NULL); } + /** Get the total number of optical photons which have been produced during this run */ unsigned long long getNumPhotons() const { return numPhotonsTotal; } @@ -252,6 +265,7 @@ class nDetRunAction : public G4UserRunAction nDetConstruction *detector; ///< Pointer to the global detector singleton nDetParticleSource *source; ///< Pointer to the thread-local particle source + nDetDetectorParams params; ///< not a Pointer to the parameters of the detector std::vector primaryTracks; ///< Vector of primary particle scatter events @@ -261,6 +275,7 @@ class nDetRunAction : public G4UserRunAction nDetDataPack data; ///< Container object for all output data nDetEventStructure evtData; ///< Container object for output event information nDetOutputStructure outData; ///< Container object for single-detector output data + nDetImplantOutputStructure outImplantData; ///< Container object for Implant output data nDetMultiOutputStructure multData; ///< Container object for multi-detector output data nDetDebugStructure debugData; ///< Container object for debug output data nDetTraceStructure traceData; ///< Container object for output traces @@ -271,8 +286,12 @@ class nDetRunAction : public G4UserRunAction unsigned long long numPhotonsDetTotal; ///< Total number of detected optical photons (thread-local) nDetDetector *startDetector; ///< Pointer to the detector used as a start signal for timing + nDetImplant *startImplant; ///< Pointer to the detector used as a start signal for timing + bool endImplant=0; + bool endDetector=0; std::vector userDetectors; ///< Vector of detectors added by the user + std::vector userImplants; ///< Vector of detectors added by the user /** Pop a primary scatter off the stack. Set all initial event conditions if this is the first scatter * @return True if the stack of primary scatters is not empty after popping off a scatter and return false otherwise @@ -284,6 +303,12 @@ class nDetRunAction : public G4UserRunAction * @return True if the detector has detected optical photons and return false otherwise */ bool processDetector(nDetDetector* det); + + /** Process a single event for a single detector + * @param det Pointer to the nDetDetector to process + * @return True if the detector has detected optical photons and return false otherwise + */ + bool processImplant(nDetImplant* imp); /** Process a single event for a single start detector * @param det Pointer to the nDetDetector to process @@ -291,6 +316,13 @@ class nDetRunAction : public G4UserRunAction * @return True if the detector has detected optical photons and return false otherwise */ bool processStartDetector(nDetDetector* det, double &startTime); + + /** Process a single event for a single start detector + * @param det Pointer to the nDetDetector to process + * @param startTime Time-of-flight of the start detector event + * @return True if the detector has detected optical photons and return false otherwise + */ + bool processStartImplant(nDetImplant* imp, double &startTime); }; #endif diff --git a/include/nDetWorldObject.hh b/include/nDetWorldObject.hh index d9952d3..6f61c2d 100644 --- a/include/nDetWorldObject.hh +++ b/include/nDetWorldObject.hh @@ -12,6 +12,7 @@ class G4LogicalVolume; class G4PVPlacement; class nDetDetector; +class nDetImplant; class nDetMaterials; /** @class nDetWorldObject @@ -104,6 +105,10 @@ class nDetWorldObject{ */ virtual void construct(nDetDetector*) = 0; + /** Construct the object and place it into an implant detector + */ + virtual void construct(nDetImplant*) = 0; + /** Return a string containing proper input string syntax */ virtual std::string syntaxStr() const = 0; @@ -180,6 +185,10 @@ class nDetWorldPrimitive : public nDetWorldObject { */ virtual void construct(nDetDetector*){ } + /** Does nothing + */ + virtual void construct(nDetImplant*){ } + /** Return a string containing proper input string syntax */ virtual std::string syntaxStr() const ; @@ -287,6 +296,11 @@ class gdmlObject : public nDetWorldObject { */ virtual void construct(nDetDetector *obj); + /** Load the GDML model and place it into a detector + * @param obj A pointer to the detector where the model will be placed + */ + virtual void construct(nDetImplant *obj); + /** Return a string containing proper input string syntax */ virtual std::string syntaxStr() const ; diff --git a/include/vertilon256.hh b/include/vertilon256.hh new file mode 100644 index 0000000..9b97d71 --- /dev/null +++ b/include/vertilon256.hh @@ -0,0 +1,268 @@ +// vertilon256.hh +// Contains the map for the 16x16 anger logic for the H13700 pmt + +#ifndef VERTILON256_HH +#define VERTILON256_HH + +namespace vertilon{ + double currents[16][16][4]={{{0.000476283,0.00046531,3.46903e-05,2.37168e-05}, + {0.000446844,0.00043587,6.41298e-05,5.31563e-05}, + {0.000417404,0.000406431,9.35693e-05,8.25959e-05}, + {0.000387965,0.000376991,0.000123009,0.000112035}, + {0.000358525,0.000347552,0.000152448,0.000141475}, + {0.000329086,0.000318112,0.000181888,0.000170914}, + {0.000299646,0.000288673,0.000211327,0.000200354}, + {0.000270206,0.000259233,0.000240767,0.000229794}, + {0.000240767,0.000229794,0.000270206,0.000259233}, + {0.000211327,0.000200354,0.000299646,0.000288673}, + {0.000181888,0.000170914,0.000329086,0.000318112}, + {0.000152448,0.000141475,0.000358525,0.000347552}, + {0.000123009,0.000112035,0.000387965,0.000376991}, + {9.35693e-05,8.25959e-05,0.000417404,0.000406431}, + {6.41298e-05,5.31563e-05,0.000446844,0.00043587}, + {3.46903e-05,2.37168e-05,0.000476283,0.00046531}}, + {{0.000480224,0.000470517,2.94833e-05,1.9776e-05}, + {0.000450175,0.000440467,5.95327e-05,4.98254e-05}, + {0.000420125,0.000410418,8.95821e-05,7.98747e-05}, + {0.000390076,0.000380369,0.000119631,0.000109924}, + {0.000360026,0.000350319,0.000149681,0.000139974}, + {0.000329977,0.00032027,0.00017973,0.000170023}, + {0.000299928,0.00029022,0.00020978,0.000200072}, + {0.000269878,0.000260171,0.000239829,0.000230122}, + {0.000239829,0.000230122,0.000269878,0.000260171}, + {0.00020978,0.000200072,0.000299928,0.00029022}, + {0.00017973,0.000170023,0.000329977,0.00032027}, + {0.000149681,0.000139974,0.000360026,0.000350319}, + {0.000119631,0.000109924,0.000390076,0.000380369}, + {8.95821e-05,7.98747e-05,0.000420125,0.000410418}, + {5.95327e-05,4.98254e-05,0.000450175,0.000440467}, + {2.94833e-05,1.9776e-05,0.000480224,0.000470517}}, + {{0.000483929,0.000475556,2.44444e-05,1.60712e-05}, + {0.000453297,0.000444923,5.50767e-05,4.67035e-05}, + {0.000422664,0.000414291,8.5709e-05,7.73358e-05}, + {0.000392032,0.000383659,0.000116341,0.000107968}, + {0.0003614,0.000353026,0.000146974,0.0001386}, + {0.000330767,0.000322394,0.000177606,0.000169233}, + {0.000300135,0.000291762,0.000208238,0.000199865}, + {0.000269503,0.00026113,0.00023887,0.000230497}, + {0.00023887,0.000230497,0.000269503,0.00026113}, + {0.000208238,0.000199865,0.000300135,0.000291762}, + {0.000177606,0.000169233,0.000330767,0.000322394}, + {0.000146974,0.0001386,0.0003614,0.000353026}, + {0.000116341,0.000107968,0.000392032,0.000383659}, + {8.5709e-05,7.73358e-05,0.000422664,0.000414291}, + {5.50767e-05,4.67035e-05,0.000453297,0.000444923}, + {2.44444e-05,1.60712e-05,0.000483929,0.000475556}}, + {{0.00048636,0.000479415,2.05849e-05,1.36403e-05}, + {0.000455308,0.000448363,5.16366e-05,4.4692e-05}, + {0.000424256,0.000417312,8.26882e-05,7.57436e-05}, + {0.000393205,0.00038626,0.00011374,0.000106795}, + {0.000362153,0.000355208,0.000144792,0.000137847}, + {0.000331101,0.000324157,0.000175843,0.000168899}, + {0.00030005,0.000293105,0.000206895,0.00019995}, + {0.000268998,0.000262054,0.000237946,0.000231002}, + {0.000237946,0.000231002,0.000268998,0.000262054}, + {0.000206895,0.00019995,0.00030005,0.000293105}, + {0.000175843,0.000168899,0.000331101,0.000324157}, + {0.000144792,0.000137847,0.000362153,0.000355208}, + {0.00011374,0.000106795,0.000393205,0.00038626}, + {8.26882e-05,7.57436e-05,0.000424256,0.000417312}, + {5.16366e-05,4.4692e-05,0.000455308,0.000448363}, + {2.05849e-05,1.36403e-05,0.00048636,0.000479415}}, + {{0.000489039,0.000483559,1.64415e-05,1.0961e-05}, + {0.000457533,0.000452052,4.7948e-05,4.24675e-05}, + {0.000426026,0.000420546,7.94545e-05,7.3974e-05}, + {0.00039452,0.000389039,0.000110961,0.00010548}, + {0.000363013,0.000357533,0.000142467,0.000136987}, + {0.000331507,0.000326026,0.000173974,0.000168493}, + {0.0003,0.00029452,0.00020548,0.0002}, + {0.000268493,0.000263013,0.000236987,0.000231507}, + {0.000236987,0.000231507,0.000268493,0.000263013}, + {0.00020548,0.0002,0.0003,0.00029452}, + {0.000173974,0.000168493,0.000331507,0.000326026}, + {0.000142467,0.000136987,0.000363013,0.000357533}, + {0.000110961,0.00010548,0.00039452,0.000389039}, + {7.94545e-05,7.3974e-05,0.000426026,0.000420546}, + {4.7948e-05,4.24675e-05,0.000457533,0.000452052}, + {1.64415e-05,1.0961e-05,0.000489039,0.000483559}}, + {{0.000490528,0.000486576,1.34239e-05,9.47197e-06}, + {0.000458721,0.000454769,4.52309e-05,4.12789e-05}, + {0.000426914,0.000422962,7.70378e-05,7.30858e-05}, + {0.000395107,0.000391155,0.000108845,0.000104893}, + {0.0003633,0.000359348,0.000140652,0.0001367}, + {0.000331493,0.000327541,0.000172459,0.000168507}, + {0.000299686,0.000295734,0.000204266,0.000200314}, + {0.000267879,0.000263927,0.000236073,0.000232121}, + {0.000236073,0.000232121,0.000267879,0.000263927}, + {0.000204266,0.000200314,0.000299686,0.000295734}, + {0.000172459,0.000168507,0.000331493,0.000327541}, + {0.000140652,0.0001367,0.0003633,0.000359348}, + {0.000108845,0.000104893,0.000395107,0.000391155}, + {7.70378e-05,7.30858e-05,0.000426914,0.000422962}, + {4.52309e-05,4.12789e-05,0.000458721,0.000454769}, + {1.34239e-05,9.47197e-06,0.000490528,0.000486576}}, + {{0.000491251,0.000488865,1.11353e-05,8.7492e-06}, + {0.000459243,0.000456857,4.3143e-05,4.07569e-05}, + {0.000427235,0.000424849,7.51507e-05,7.27646e-05}, + {0.000395228,0.000392842,0.000107158,0.000104772}, + {0.00036322,0.000360834,0.000139166,0.00013678}, + {0.000331212,0.000328826,0.000171174,0.000168788}, + {0.000299205,0.000296818,0.000203182,0.000200795}, + {0.000267197,0.000264811,0.000235189,0.000232803}, + {0.000235189,0.000232803,0.000267197,0.000264811}, + {0.000203182,0.000200795,0.000299205,0.000296818}, + {0.000171174,0.000168788,0.000331212,0.000328826}, + {0.000139166,0.00013678,0.00036322,0.000360834}, + {0.000107158,0.000104772,0.000395228,0.000392842}, + {7.51507e-05,7.27646e-05,0.000427235,0.000424849}, + {4.3143e-05,4.07569e-05,0.000459243,0.000456857}, + {1.11353e-05,8.7492e-06,0.000491251,0.000488865}}, + {{0.000491204,0.000490406,9.59361e-06,8.79575e-06}, + {0.000459097,0.000458299,4.1701e-05,4.09031e-05}, + {0.000426989,0.000426192,7.38084e-05,7.30105e-05}, + {0.000394882,0.000394084,0.000105916,0.000105118}, + {0.000362775,0.000361977,0.000138023,0.000137225}, + {0.000330667,0.00032987,0.00017013,0.000169333}, + {0.00029856,0.000297762,0.000202238,0.00020144}, + {0.000266453,0.000265655,0.000234345,0.000233547}, + {0.000234345,0.000233547,0.000266453,0.000265655}, + {0.000202238,0.00020144,0.00029856,0.000297762}, + {0.00017013,0.000169333,0.000330667,0.00032987}, + {0.000138023,0.000137225,0.000362775,0.000361977}, + {0.000105916,0.000105118,0.000394882,0.000394084}, + {7.38084e-05,7.30105e-05,0.000426989,0.000426192}, + {4.1701e-05,4.09031e-05,0.000459097,0.000458299}, + {9.59361e-06,8.79575e-06,0.000491204,0.000490406}}, + {{0.000490406,0.000491204,8.79575e-06,9.59361e-06}, + {0.000458299,0.000459097,4.09031e-05,4.1701e-05}, + {0.000426192,0.000426989,7.30105e-05,7.38084e-05}, + {0.000394084,0.000394882,0.000105118,0.000105916}, + {0.000361977,0.000362775,0.000137225,0.000138023}, + {0.00032987,0.000330667,0.000169333,0.00017013}, + {0.000297762,0.00029856,0.00020144,0.000202238}, + {0.000265655,0.000266453,0.000233547,0.000234345}, + {0.000233547,0.000234345,0.000265655,0.000266453}, + {0.00020144,0.000202238,0.000297762,0.00029856}, + {0.000169333,0.00017013,0.00032987,0.000330667}, + {0.000137225,0.000138023,0.000361977,0.000362775}, + {0.000105118,0.000105916,0.000394084,0.000394882}, + {7.30105e-05,7.38084e-05,0.000426192,0.000426989}, + {4.09031e-05,4.1701e-05,0.000458299,0.000459097}, + {8.79575e-06,9.59361e-06,0.000490406,0.000491204}}, + {{0.000488865,0.000491251,8.7492e-06,1.11353e-05}, + {0.000456857,0.000459243,4.07569e-05,4.3143e-05}, + {0.000424849,0.000427235,7.27646e-05,7.51507e-05}, + {0.000392842,0.000395228,0.000104772,0.000107158}, + {0.000360834,0.00036322,0.00013678,0.000139166}, + {0.000328826,0.000331212,0.000168788,0.000171174}, + {0.000296818,0.000299205,0.000200795,0.000203182}, + {0.000264811,0.000267197,0.000232803,0.000235189}, + {0.000232803,0.000235189,0.000264811,0.000267197}, + {0.000200795,0.000203182,0.000296818,0.000299205}, + {0.000168788,0.000171174,0.000328826,0.000331212}, + {0.00013678,0.000139166,0.000360834,0.00036322}, + {0.000104772,0.000107158,0.000392842,0.000395228}, + {7.27646e-05,7.51507e-05,0.000424849,0.000427235}, + {4.07569e-05,4.3143e-05,0.000456857,0.000459243}, + {8.7492e-06,1.11353e-05,0.000488865,0.000491251}}, + {{0.000486576,0.000490528,9.47197e-06,1.34239e-05}, + {0.000454769,0.000458721,4.12789e-05,4.52309e-05}, + {0.000422962,0.000426914,7.30858e-05,7.70378e-05}, + {0.000391155,0.000395107,0.000104893,0.000108845}, + {0.000359348,0.0003633,0.0001367,0.000140652}, + {0.000327541,0.000331493,0.000168507,0.000172459}, + {0.000295734,0.000299686,0.000200314,0.000204266}, + {0.000263927,0.000267879,0.000232121,0.000236073}, + {0.000232121,0.000236073,0.000263927,0.000267879}, + {0.000200314,0.000204266,0.000295734,0.000299686}, + {0.000168507,0.000172459,0.000327541,0.000331493}, + {0.0001367,0.000140652,0.000359348,0.0003633}, + {0.000104893,0.000108845,0.000391155,0.000395107}, + {7.30858e-05,7.70378e-05,0.000422962,0.000426914}, + {4.12789e-05,4.52309e-05,0.000454769,0.000458721}, + {9.47197e-06,1.34239e-05,0.000486576,0.000490528}}, + {{0.000483559,0.000489039,1.0961e-05,1.64415e-05}, + {0.000452052,0.000457533,4.24675e-05,4.7948e-05}, + {0.000420546,0.000426026,7.3974e-05,7.94545e-05}, + {0.000389039,0.00039452,0.00010548,0.000110961}, + {0.000357533,0.000363013,0.000136987,0.000142467}, + {0.000326026,0.000331507,0.000168493,0.000173974}, + {0.00029452,0.0003,0.0002,0.00020548}, + {0.000263013,0.000268493,0.000231507,0.000236987}, + {0.000231507,0.000236987,0.000263013,0.000268493}, + {0.0002,0.00020548,0.00029452,0.0003}, + {0.000168493,0.000173974,0.000326026,0.000331507}, + {0.000136987,0.000142467,0.000357533,0.000363013}, + {0.00010548,0.000110961,0.000389039,0.00039452}, + {7.3974e-05,7.94545e-05,0.000420546,0.000426026}, + {4.24675e-05,4.7948e-05,0.000452052,0.000457533}, + {1.0961e-05,1.64415e-05,0.000483559,0.000489039}}, + {{0.000479415,0.00048636,1.36403e-05,2.05849e-05}, + {0.000448363,0.000455308,4.4692e-05,5.16366e-05}, + {0.000417312,0.000424256,7.57436e-05,8.26882e-05}, + {0.00038626,0.000393205,0.000106795,0.00011374}, + {0.000355208,0.000362153,0.000137847,0.000144792}, + {0.000324157,0.000331101,0.000168899,0.000175843}, + {0.000293105,0.00030005,0.00019995,0.000206895}, + {0.000262054,0.000268998,0.000231002,0.000237946}, + {0.000231002,0.000237946,0.000262054,0.000268998}, + {0.00019995,0.000206895,0.000293105,0.00030005}, + {0.000168899,0.000175843,0.000324157,0.000331101}, + {0.000137847,0.000144792,0.000355208,0.000362153}, + {0.000106795,0.00011374,0.00038626,0.000393205}, + {7.57436e-05,8.26882e-05,0.000417312,0.000424256}, + {4.4692e-05,5.16366e-05,0.000448363,0.000455308}, + {1.36403e-05,2.05849e-05,0.000479415,0.00048636}}, + {{0.000475556,0.000483929,1.60712e-05,2.44444e-05}, + {0.000444923,0.000453297,4.67035e-05,5.50767e-05}, + {0.000414291,0.000422664,7.73358e-05,8.5709e-05}, + {0.000383659,0.000392032,0.000107968,0.000116341}, + {0.000353026,0.0003614,0.0001386,0.000146974}, + {0.000322394,0.000330767,0.000169233,0.000177606}, + {0.000291762,0.000300135,0.000199865,0.000208238}, + {0.00026113,0.000269503,0.000230497,0.00023887}, + {0.000230497,0.00023887,0.00026113,0.000269503}, + {0.000199865,0.000208238,0.000291762,0.000300135}, + {0.000169233,0.000177606,0.000322394,0.000330767}, + {0.0001386,0.000146974,0.000353026,0.0003614}, + {0.000107968,0.000116341,0.000383659,0.000392032}, + {7.73358e-05,8.5709e-05,0.000414291,0.000422664}, + {4.67035e-05,5.50767e-05,0.000444923,0.000453297}, + {1.60712e-05,2.44444e-05,0.000475556,0.000483929}}, + {{0.000470517,0.000480224,1.9776e-05,2.94833e-05}, + {0.000440467,0.000450175,4.98254e-05,5.95327e-05}, + {0.000410418,0.000420125,7.98747e-05,8.95821e-05}, + {0.000380369,0.000390076,0.000109924,0.000119631}, + {0.000350319,0.000360026,0.000139974,0.000149681}, + {0.00032027,0.000329977,0.000170023,0.00017973}, + {0.00029022,0.000299928,0.000200072,0.00020978}, + {0.000260171,0.000269878,0.000230122,0.000239829}, + {0.000230122,0.000239829,0.000260171,0.000269878}, + {0.000200072,0.00020978,0.00029022,0.000299928}, + {0.000170023,0.00017973,0.00032027,0.000329977}, + {0.000139974,0.000149681,0.000350319,0.000360026}, + {0.000109924,0.000119631,0.000380369,0.000390076}, + {7.98747e-05,8.95821e-05,0.000410418,0.000420125}, + {4.98254e-05,5.95327e-05,0.000440467,0.000450175}, + {1.9776e-05,2.94833e-05,0.000470517,0.000480224}}, + {{0.00046531,0.000476283,2.37168e-05,3.46903e-05}, + {0.00043587,0.000446844,5.31563e-05,6.41298e-05}, + {0.000406431,0.000417404,8.25959e-05,9.35693e-05}, + {0.000376991,0.000387965,0.000112035,0.000123009}, + {0.000347552,0.000358525,0.000141475,0.000152448}, + {0.000318112,0.000329086,0.000170914,0.000181888}, + {0.000288673,0.000299646,0.000200354,0.000211327}, + {0.000259233,0.000270206,0.000229794,0.000240767}, + {0.000229794,0.000240767,0.000259233,0.000270206}, + {0.000200354,0.000211327,0.000288673,0.000299646}, + {0.000170914,0.000181888,0.000318112,0.000329086}, + {0.000141475,0.000152448,0.000347552,0.000358525}, + {0.000112035,0.000123009,0.000376991,0.000387965}, + {8.25959e-05,9.35693e-05,0.000406431,0.000417404}, + {5.31563e-05,6.41298e-05,0.00043587,0.000446844}, + {2.37168e-05,3.46903e-05,0.00046531,0.000476283}} + }; +} + + +#endif \ No newline at end of file diff --git a/mac/alphatest.mac b/mac/alphatest.mac new file mode 100644 index 0000000..adafdfe --- /dev/null +++ b/mac/alphatest.mac @@ -0,0 +1,114 @@ +# hagrid.mac +# Cory R Thornsberry +# Simulates an elliptical bar (football) with a 1 MeV beam of neutrons + +/nDet/implant/setPmtDimensions 50.4 + +# Mylar and optical grease thickness. +/nDet/implant/setMylarThickness 0.025 +/nDet/implant/setGreaseThickness 0.1 + +################ +# OUTPUT SETUP # +################ + +# Set the output filename prefix +/nDet/output/filename alphaTests.root +/nDet/output/title ribf168 exp setup with ~16 Hagrid and Pspmt implant and 1. MeV gamma circle beam w 5 mm rad no seg +/nDet/output/debug false + +# Setup information about the PMT response +/nDet/output/trace/setRisetime 2 +/nDet/output/trace/setFalltime 20 +/nDet/output/trace/setTimeSpread 0.35 +/nDet/output/trace/setGain 2E4 +/nDet/output/trace/setBaseline 7.5 +/nDet/output/trace/setJitter 0.15 + +# Setup the PMT light pulse output +/nDet/output/trace/setTraceDelay 60 +/nDet/output/trace/setTraceLength 500 +/nDet/output/trace/setBitRange 16 + +/nDet/output/trace/setCfdFraction 0.5 +/nDet/output/trace/setIntegralLow 5 + +################## +# IMPLANT SETUP # +################## + +# IMPLANT Setup +/nDet/implant/setMaterial yso +# 5 mm thick scintillator +/nDet/implant/setDetectorLength 0.5 +/nDet/implant/setDetectorWidth 5.08 +/nDet/implant/setDetectorThickness 50.8 +/nDet/implant/setWindowThickness 1. +/nDet/implant/setNumColumns 1 +/nDet/implant/setNumRows 1 +#/nDet/implant/setNumColumns 24 +#/nDet/implant/setNumRows 24 +#/nDet/implant/setStart 1 + +# Set the wrapping. +/nDet/implant/setWrapping perfect + +# Load PSPMT gain matrix +# NOTE: This MUST be done AFTER calling '/nDet/implant/update' otherwise it will fail +#/nDet/implant/setGainMatrix ~/opt/NEXTSim/gain/hamamatsuH12700A_LA0967.dat +/nDet/implant/setGainMatrix hamamatsuH12700A_LA0967.dat +# Load PSPMT spectral response function +/nDet/implant/setSpectralResponse ~/opt/NEXTSim/spectral/hamamatsuH12700A.root + +# Set the position and rotation of the detector in the lab frame. +/nDet/implant/setPosition 0 0 0 cm +#/nDet/implant/setCylindrical 0.5 0 0 +/nDet/implant/setRotation 0 270 0 +/nDet/implant/addGeometry module + +/nDet/implant/addDiffuserLayer 50 50 0.1 +#/nDet/implant/addLightGuide 50 50 50 50 5 +#/nDet/segLightGuide/thickness 10 +#/nDet/implant/setSegmentedLightGuide 24 24 5 50.8 50.8 45 45 G4_Pyrex_Glass + + +# Update the detector. +/nDet/implant/update +/nDet/output/trace/setIntegralHigh 10 + +################## +# HAGRID SETUP # +################## + +#### Aluminum case thickness set to 0.305 cm + +# Ellipse prototype +#/nDet/implant/setMaterial labr3 +#/nDet/implant/setDetectorLength 5.08 cm +#/nDet/implant/setDetectorWidth 5.08 cm +#/nDet/implant/setMylarThickness 3.05 mm +#/nDet/implant/setWrapping aluminum +# +### Update the detector. +#/nDet/implant/addArray hagrid 5.7 0 180 16 +#/nDet/implant/update + +################ +# SOURCE SETUP # +################ + +# Available source types: 137Cs 60Co 133Ba 241Am 90Sr 252Cf +#/nDet/source/type 60Co + +/nDet/source/type alpha 5. +/nDet/source/spot 0.001 mm +/nDet/source/shape circle + +# Set isotropic source (0=off, 1=psuedo, 2=realistic) +/nDet/source/iso 2 + +############### +# RUN CONTROL # +############### + +/run/beamOn 100000 diff --git a/mac/cebrtest.mac b/mac/cebrtest.mac new file mode 100644 index 0000000..6a41462 --- /dev/null +++ b/mac/cebrtest.mac @@ -0,0 +1,137 @@ +# +# create empty scene +# + + +# Use a GDML file for the light guides. +# NOTE: This MUST be done BEFORE calling '/nDet/implant/update' +#/nDet/implant/loadGDML gdml/modifiedLightGuide.gdml +#/nDet/implant/loadGDML gdml/nonSegmentedLightGuide.gdml +#/nDet/implant/setTrapezoidLength 1.27 + +#/nDet/implant/setGDMLrotation 90 0 0 + +# This is important to set for GDML light-guide because +# we cannot obtain the information from the model itself. +/nDet/implant/setPmtDimensions 50.0 + + +# Mylar and optical grease thickness. +/nDet/implant/setMylarThickness 0.3 +/nDet/implant/setGreaseThickness 0.5 + +# Light +/nDet/implant/setDiffuserLength 1.5 + +# Choose Scintillator +/nDet/implant/setMaterial yso + +# PMT segmentation. +/nDet/implant/setPmtColumns 8 +/nDet/implant/setPmtRows 8 + +################## +# DETECTOR SETUP # +################## + +# Pspmt +/nDet/implant/setDetectorLength 0.5 #in cm +#/nDet/implant/setDetectorWidth 5.08 +#/nDet/implant/setDetectorThickness 50.8 +/nDet/implant/setDetectorWidth 4.27 +/nDet/implant/setDetectorThickness 42.7 +/nDet/implant/setWindowThickness 1. +/nDet/implant/setNumColumns 8 +/nDet/implant/setNumRows 8 +/nDet/implant/setStart 1 + +# Set the wrapping. +/nDet/implant/setWrapping perfect + +# Load PSPMT gain matrix +# NOTE: This MUST be done AFTER calling '/nDet/implant/update' otherwise it will fail +#/nDet/implant/setGainMatrix ~/opt/NEXTSim/gain/hamamatsuH12700A_LA0967.dat +/nDet/implant/setGainMatrix hamamatsuH12700A_LA0967.dat +# Load PSPMT spectral response function +/nDet/implant/setSpectralResponse ~/opt/NEXTSim/spectral/hamamatsuH12700A.root + +# Set the position and rotation of the detector in the lab frame. +/nDet/implant/setPosition 0 0 0 cm +#/nDet/implant/setCylindrical 0.5 0 0 +/nDet/implant/setRotation 0 270 0 +/nDet/implant/addGeometry module + +/nDet/implant/addDiffuserLayer 50 50 0.1 +#/nDet/implant/addLightGuide 50 50 50 50 5 +#/nDet/segLightGuide/thickness 10 +#/nDet/implant/setSegmentedLightGuide 24 24 5 50.8 50.8 45 45 G4_Pyrex_Glass + + +# Update the detector. +/nDet/implant/update + + +################ +# OUTPUT SETUP # +################ + +# Set the output filename prefix +/nDet/output/filename cebrtestShape.root +/nDet/output/title PSPMT, 0.5 MeV, 1 m from detector +#/nDet/output/index 69 +#/nDet/output/overwrite true +#/nDet/output/persistent true +#/nDet/output/enabled false +#/nDet/output/badEvents true +/nDet/output/debug true + +# Setup information about the PMT response +/nDet/output/trace/setRisetime 2 +/nDet/output/trace/setFalltime 20 +/nDet/output/trace/setTimeSpread 0.35 +/nDet/output/trace/setGain 1E4 +/nDet/output/trace/setBaseline 7.5 +/nDet/output/trace/setJitter 0.15 + +# Setup the PMT light pulse output +#/nDet/output/trace/enabled true +/nDet/output/trace/setTraceDelay 60 +/nDet/output/trace/setTraceLength 500 +/nDet/output/trace/setBitRange 16 +/nDet/output/trace/setGain 1000 +/nDet/output/trace/setCfdFraction 0.5 +/nDet/output/trace/setIntegralLow 5 +/nDet/output/trace/setIntegralHigh 10 + +################ +# SOURCE SETUP # +################ + +# Available source types: 137Cs 60Co 133Ba 241Am 90Sr 252Cf +#/nDet/source/type 252Cf + +#/nDet/source/type alpha 5 +/nDet/source/type 90Sr +/nDet/source/spot 20 #half-width for beam +/nDet/source/shape circle +#/nDet/source/beam 137Cs +#/nDet/source/beam gamma 0.03 + +#/nDet/source/spot 38.1 +#/nDet/source/spot 25.4 +#/nDet/source/spot 12.7 + +# Optical laser beam. +#/nDet/source/beam laser 360 +#/nDet/source/position 20 0 0 cm +#/nDet/source/direction 0 0 0 + +/nDet/source/iso 1 + +#/nDet/source/range 1.175 1.225 0 + +############### +# RUN CONTROL # +############### + +/run/beamOn 10000000 diff --git a/mac/cylinder.mac b/mac/cylinder.mac new file mode 100644 index 0000000..028349d --- /dev/null +++ b/mac/cylinder.mac @@ -0,0 +1,75 @@ +# cylinder.mac +# Cory R Thornsberry +# Simulates an elliptical bar (football) with a 1 MeV beam of neutrons + +/nDet/detector/setPmtDimensions 6 + +# Mylar and optical grease thickness. +/nDet/detector/setMylarThickness 0.025 +/nDet/detector/setGreaseThickness 0.1 + +################ +# OUTPUT SETUP # +################ + +# Set the output filename prefix +/nDet/output/filename cylinder.root +/nDet/output/title 10 cm cylinder prototype w/ 6x6 mm^2 SiPMs and 1 MeV neutron pencil beam at 1 m (wrapped with mylar) +/nDet/output/debug true + +# Setup information about the PMT response +/nDet/output/trace/setRisetime 2 +/nDet/output/trace/setFalltime 20 +/nDet/output/trace/setTimeSpread 0.35 +/nDet/output/trace/setGain 2E4 +/nDet/output/trace/setBaseline 7.5 +/nDet/output/trace/setJitter 0.15 + +# Setup the PMT light pulse output +/nDet/output/trace/setTraceDelay 60 +/nDet/output/trace/setTraceLength 500 +/nDet/output/trace/setBitRange 16 + +/nDet/output/trace/setCfdFraction 0.5 +/nDet/output/trace/setIntegralLow 5 +/nDet/output/trace/setIntegralHigh 10 + +################## +# DETECTOR SETUP # +################## + +# Ellipse prototype +/nDet/detector/setDetectorLength 6 +/nDet/detector/setDetectorThickness 6 +/nDet/detector/setWrapping mylar + +/nDet/detector/setTrapezoidLength 2 +/nDet/detector/setTrapezoidAngle 45 + +# Set the position and rotation of the detector in the lab frame. +/nDet/detector/setPosition 100 0 0 cm +/nDet/detector/setRotation 0 0 90 + +# Update the detector. +/nDet/detector/addGeometry cylinder +/nDet/detector/update + +################ +# SOURCE SETUP # +################ + +# Available source types: 137Cs 60Co 133Ba 241Am 90Sr 252Cf +#/nDet/source/type 60Co + +/nDet/source/type neutron 1 +#/nDet/source/spot 20 + +# Set isotropic source (0=off, 1=psuedo, 2=realistic) +#/nDet/source/iso 1 + +############### +# RUN CONTROL # +############### + +#/run/beamOn 10000 + diff --git a/mac/fdsiImplant.mac b/mac/fdsiImplant.mac new file mode 100644 index 0000000..95ee43f --- /dev/null +++ b/mac/fdsiImplant.mac @@ -0,0 +1,142 @@ +# +# create empty scene +# + + +# Use a GDML file for the light guides. +# NOTE: This MUST be done BEFORE calling '/nDet/implant/update' +#/nDet/implant/loadGDML gdml/modifiedLightGuide.gdml +#/nDet/implant/loadGDML gdml/nonSegmentedLightGuide.gdml +#/nDet/implant/setTrapezoidLength 1.27 + +#/nDet/implant/setGDMLrotation 90 0 0 + +# This is important to set for GDML light-guide because +# we cannot obtain the information from the model itself. +/nDet/implant/setPmtDimensions 50.0 + + +# Mylar and optical grease thickness. +/nDet/implant/setMylarThickness 0.025 +/nDet/implant/setGreaseThickness 0.5 + +# Light +/nDet/implant/setDiffuserLength 1.5 + +# Choose Scintillator +/nDet/implant/setMaterial yso + +# PMT segmentation. +/nDet/implant/setPmtColumns 8 +/nDet/implant/setPmtRows 8 + +################## +# DETECTOR SETUP # +################## + +# NEXT 2x2x10 in^3 +/nDet/implant/setDetectorLength 0.5 +/nDet/implant/setDetectorWidth 5.08 +/nDet/implant/setDetectorThickness 50.8 +/nDet/implant/setWindowThickness 1. +/nDet/implant/setNumColumns 48 +/nDet/implant/setNumRows 48 +/nDet/implant/setStart 1 + +# NEXT 3x3x10 in^3 +#/nDet/implant/setDetectorLength 5.4 +#/nDet/implant/setDetectorWidth 7.62 +#/nDet/implant/setDetectorThickness 76.2 +#/nDet/implant/setNumColumns 12 +#/nDet/implant/setNumRows 6 + +# Set the wrapping. +/nDet/implant/setWrapping perfect + +# Load PSPMT gain matrix +# NOTE: This MUST be done AFTER calling '/nDet/implant/update' otherwise it will fail +#/nDet/implant/setGainMatrix ~/opt/NEXTSim/gain/hamamatsuH12700A_LA0967.dat +/nDet/implant/setGainMatrix hamamatsuH12700A_LA0967.dat +# Load PSPMT spectral response function +/nDet/implant/setSpectralResponse ~/opt/NEXTSim/spectral/hamamatsuH12700A.root + +# Set the position and rotation of the detector in the lab frame. +/nDet/implant/setPosition 0 0 0 cm +#/nDet/implant/setCylindrical 0.5 0 0 +/nDet/implant/setRotation 0 270 0 +/nDet/implant/addGeometry module + +/nDet/implant/addDiffuserLayer 50 50 0.1 +#/nDet/implant/addLightGuide 50 50 50 50 5 +#/nDet/segLightGuide/thickness 10 +/nDet/implant/setSegmentedLightGuide 16 16 5 50.8 50.8 45 45 G4_Pyrex_Glass + + +# Update the detector. +/nDet/implant/update + + +################ +# OUTPUT SETUP # +################ + +# Set the output filename prefix +/nDet/output/filename fdsiImplant.root +/nDet/output/title SiPM array, Large MeV, 1 m from detector +#/nDet/output/index 69 +#/nDet/output/overwrite true +#/nDet/output/persistent true +#/nDet/output/enabled false +#/nDet/output/badEvents true +/nDet/output/debug true + +# Setup information about the PMT response +/nDet/output/trace/setRisetime 2 +/nDet/output/trace/setFalltime 20 +/nDet/output/trace/setTimeSpread 0.35 +/nDet/output/trace/setGain 1E4 +/nDet/output/trace/setBaseline 7.5 +/nDet/output/trace/setJitter 0.15 + +# Setup the PMT light pulse output +#/nDet/output/trace/enabled true +/nDet/output/trace/setTraceDelay 60 +/nDet/output/trace/setTraceLength 500 +/nDet/output/trace/setBitRange 16 +/nDet/output/trace/setGain 1000 +/nDet/output/trace/setCfdFraction 0.5 +/nDet/output/trace/setIntegralLow 5 +/nDet/output/trace/setIntegralHigh 10 + +################ +# SOURCE SETUP # +################ + +# Available source types: 137Cs 60Co 133Ba 241Am 90Sr 252Cf +#/nDet/source/type 252Cf + +#/nDet/source/type alpha 5 +/nDet/source/type electron 0.1 +/nDet/source/spot 0.1 #half-width for beam +/nDet/source/shape circle +#/nDet/source/beam 137Cs +#/nDet/source/beam gamma 0.03 + +#/nDet/source/spot 38.1 +#/nDet/source/spot 25.4 +#/nDet/source/spot 12.7 + +# Optical laser beam. +#/nDet/source/beam laser 360 +#/nDet/source/position 20 0 0 cm +#/nDet/source/direction 0 0 0 + +/nDet/source/iso 1 + +#/nDet/source/range 1.175 1.225 0 + +############### +# RUN CONTROL # +############### + +#/run/beamOn 200000 diff --git a/mac/hagrid.mac b/mac/hagrid.mac new file mode 100644 index 0000000..87ef101 --- /dev/null +++ b/mac/hagrid.mac @@ -0,0 +1,85 @@ +# hagrid.mac +# Cory R Thornsberry +# Simulates an elliptical bar (football) with a 1 MeV beam of neutrons + +/nDet/implant/setPmtDimensions 50 + +# Mylar and optical grease thickness. +/nDet/implant/setMylarThickness 0.025 +/nDet/implant/setGreaseThickness 0.1 + +################ +# OUTPUT SETUP # +################ + +# Set the output filename prefix +/nDet/output/filename hagrid.root +/nDet/output/title 2 in hagrid no implant and gamma with 1 MeV +/nDet/output/debug false + +# Setup information about the PMT response +/nDet/output/trace/setRisetime 2 +/nDet/output/trace/setFalltime 20 +/nDet/output/trace/setTimeSpread 0.35 +/nDet/output/trace/setGain 2E4 +/nDet/output/trace/setBaseline 7.5 +/nDet/output/trace/setJitter 0.15 + +# Setup the PMT light pulse output +/nDet/output/trace/setTraceDelay 60 +/nDet/output/trace/setTraceLength 500 +/nDet/output/trace/setBitRange 16 + +/nDet/output/trace/setCfdFraction 0.5 +/nDet/output/trace/setIntegralLow 5 +/nDet/output/trace/setIntegralHigh 10 + +################## +# DETECTOR SETUP # +################## + +# Ellipse prototype +/nDet/implant/setMaterial labr3 +/nDet/implant/setDetectorLength 5.08 +/nDet/implant/setDetectorWidth 5.08 +/nDet/implant/setMylarThickness 3.05 mm +/nDet/implant/setWrapping aluminum + +#/nDet/implant/setTrapezoidLength 2 +#/nDet/implant/setTrapezoidAngle 45 + +# Set the position and rotation of the detector in the lab frame. +#/nDet/implant/setPosition 0 0 2.769 cm +#/nDet/implant/setRotation 0 0 90 + +# Update the detector. +#/nDet/implant/addGeometry hagrid +/nDet/implant/addArray hagrid 5.7 0 180 16 +/nDet/implant/update + +## Set the position and rotation of the detector in the lab frame. +#/nDet/implant/setPosition 0 0 -2.769 cm +#/nDet/implant/setRotation 0 180 90 +# +## Update the detector. +#/nDet/implant/addGeometry hagrid +#/nDet/implant/update + +################ +# SOURCE SETUP # +################ + +# Available source types: 137Cs 60Co 133Ba 241Am 90Sr 252Cf +#/nDet/source/type 60Co + +/nDet/source/type gamma 1 +#/nDet/source/spot 5 mm + +# Set isotropic source (0=off, 1=psuedo, 2=realistic) +/nDet/source/iso 2 + +############### +# RUN CONTROL # +############### + +/run/beamOn 1000000 diff --git a/mac/ionTest.mac b/mac/ionTest.mac new file mode 100644 index 0000000..1dfaf11 --- /dev/null +++ b/mac/ionTest.mac @@ -0,0 +1,144 @@ +# +# create empty scene +# + + +# Use a GDML file for the light guides. +# NOTE: This MUST be done BEFORE calling '/nDet/implant/update' +#/nDet/implant/loadGDML gdml/modifiedLightGuide.gdml +#/nDet/implant/loadGDML gdml/nonSegmentedLightGuide.gdml +#/nDet/implant/setTrapezoidLength 1.27 + +#/nDet/implant/setGDMLrotation 90 0 0 + +# This is important to set for GDML light-guide because +# we cannot obtain the information from the model itself. +/nDet/implant/setPmtDimensions 50.0 + + +# Mylar and optical grease thickness. +/nDet/implant/setMylarThickness 0.025 +/nDet/implant/setGreaseThickness 0.5 + +# Light +/nDet/implant/setDiffuserLength 1.5 + +# Choose Scintillator +/nDet/implant/setMaterial yso + +# PMT segmentation. +/nDet/implant/setPmtColumns 8 +/nDet/implant/setPmtRows 8 + +################## +# DETECTOR SETUP # +################## + +# NEXT 2x2x10 in^3 +/nDet/implant/setDetectorLength 1.2 +/nDet/implant/setDetectorWidth 5.08 +/nDet/implant/setDetectorThickness 50.8 +/nDet/implant/setWindowThickness 1. +/nDet/implant/setNumColumns 24 +/nDet/implant/setNumRows 24 +/nDet/implant/setStart 1 + +# NEXT 3x3x10 in^3 +#/nDet/implant/setDetectorLength 5.4 +#/nDet/implant/setDetectorWidth 7.62 +#/nDet/implant/setDetectorThickness 76.2 +#/nDet/implant/setNumColumns 12 +#/nDet/implant/setNumRows 6 + +# Set the wrapping. +/nDet/implant/setWrapping perfect + +# Load PSPMT gain matrix +# NOTE: This MUST be done AFTER calling '/nDet/implant/update' otherwise it will fail +#/nDet/implant/setGainMatrix ~/opt/NEXTSim/gain/hamamatsuH12700A_LA0967.dat +/nDet/implant/setGainMatrix hamamatsuH12700A_LA0967.dat +# Load PSPMT spectral response function +/nDet/implant/setSpectralResponse ~/opt/NEXTSim/spectral/hamamatsuH12700A.root + +# Set the position and rotation of the detector in the lab frame. +/nDet/implant/setPosition 0 0 0 cm +#/nDet/implant/setCylindrical 0.5 0 0 +/nDet/implant/setRotation 0 270 0 +/nDet/implant/addGeometry module + +/nDet/implant/addDiffuserLayer 50 50 0.1 +#/nDet/implant/addLightGuide 50 50 50 50 5 +#/nDet/segLightGuide/thickness 10 +# setSegmentedLightGuide <# x seg> <# y seg> +/nDet/implant/setSegmentedLightGuide 24 24 5 50.8 50.8 45 45 G4_Pyrex_Glass + + +# Update the detector. +/nDet/implant/update + + +################ +# OUTPUT SETUP # +################ + +# Set the output filename prefix +/nDet/output/filename ionTest_24O_24x24.root +/nDet/output/title PSPMT, 24O 2 GeV +#/nDet/output/index 69 +#/nDet/output/overwrite true +#/nDet/output/persistent true +#/nDet/output/enabled false +#/nDet/output/badEvents true +/nDet/output/debug true + +# Setup information about the PMT response +/nDet/output/trace/setRisetime 2 +/nDet/output/trace/setFalltime 20 +/nDet/output/trace/setTimeSpread 0.35 +/nDet/output/trace/setGain 1E4 +/nDet/output/trace/setBaseline 7.5 +/nDet/output/trace/setJitter 0.15 + +# Setup the PMT light pulse output +#/nDet/output/trace/enabled true +/nDet/output/trace/setTraceDelay 60 +/nDet/output/trace/setTraceLength 500 +/nDet/output/trace/setBitRange 16 +/nDet/output/trace/setGain 1000 +/nDet/output/trace/setCfdFraction 0.5 +/nDet/output/trace/setIntegralLow 5 +/nDet/output/trace/setIntegralHigh 10 + +################ +# SOURCE SETUP # +################ + +# Available source types: 137Cs 60Co 133Ba 241Am 90Sr 252Cf +#/nDet/source/type 252Cf + +#/nDet/source/type alpha 5 +#/nDet/source/type 90Sr +/nDet/source/spot 25 #half-width for beam +/nDet/source/shape circle +#/nDet/source/beam 137Cs +/nDet/source/position -20 0 0 #default to cm.. best above beam +/nDet/source/type ion 2000 24 8 # Example for 24O at 2 GeV + +#/nDet/source/spot 38.1 +#/nDet/source/spot 25.4 +#/nDet/source/spot 12.7 + +# Optical laser beam. +#/nDet/source/beam laser 360 +/nDet/source/direction 1 0 0 + + +#/nDet/source/iso 1 + +#/nDet/source/range 1.175 1.225 0 + +############### +# RUN CONTROL # +############### + +/run/beamOn 200000 diff --git a/mac/mtasImplant.mac b/mac/mtasImplant.mac new file mode 100644 index 0000000..8683b21 --- /dev/null +++ b/mac/mtasImplant.mac @@ -0,0 +1,143 @@ +# +# create empty scene +# + + +# Use a GDML file for the light guides. +# NOTE: This MUST be done BEFORE calling '/nDet/implant/update' +#/nDet/implant/loadGDML gdml/modifiedLightGuide.gdml +#/nDet/implant/loadGDML gdml/nonSegmentedLightGuide.gdml +#/nDet/implant/setTrapezoidLength 1.27 + +#/nDet/implant/setGDMLrotation 90 0 0 + +# This is important to set for GDML light-guide because +# we cannot obtain the information from the model itself. +/nDet/implant/setPmtDimensions 50.0 + + +# Mylar and optical grease thickness. +/nDet/implant/setMylarThickness 0.025 +/nDet/implant/setGreaseThickness 0.5 + +# Light +/nDet/implant/setDiffuserLength 1.5 + +# Choose Scintillator +/nDet/implant/setMaterial yso + +# PMT segmentation. +/nDet/implant/setPmtColumns 8 +/nDet/implant/setPmtRows 8 + +################## +# DETECTOR SETUP # +################## + +# NEXT 2x2x10 in^3 +/nDet/implant/setDetectorLength 0.5 +/nDet/implant/setDetectorWidth 5.08 +/nDet/implant/setDetectorThickness 50.8 +/nDet/implant/setWindowThickness 1. +/nDet/implant/setNumColumns 48 +/nDet/implant/setNumRows 48 +/nDet/implant/setStart 1 + +# NEXT 3x3x10 in^3 +#/nDet/implant/setDetectorLength 5.4 +#/nDet/implant/setDetectorWidth 7.62 +#/nDet/implant/setDetectorThickness 76.2 +#/nDet/implant/setNumColumns 12 +#/nDet/implant/setNumRows 6 + +# Set the wrapping. +/nDet/implant/setWrapping perfect + +# Load PSPMT gain matrix +# NOTE: This MUST be done AFTER calling '/nDet/implant/update' otherwise it will fail +#/nDet/implant/setGainMatrix ~/opt/NEXTSim/gain/hamamatsuH12700A_LA0967.dat +/nDet/implant/setGainMatrix hamamatsuH12700A_LA0967.dat +# Load PSPMT spectral response function +/nDet/implant/setSpectralResponse ~/opt/NEXTSim/spectral/hamamatsuH12700A.root + +# Set the position and rotation of the detector in the lab frame. +/nDet/implant/setPosition 0 0 0 cm +#/nDet/implant/setCylindrical 0.5 0 0 +/nDet/implant/setRotation 0 270 0 +/nDet/implant/addGeometry module + +/nDet/implant/addDiffuserLayer 50 50 0.1 +#/nDet/implant/addLightGuide 50 50 50 50 5 +#/nDet/segLightGuide/thickness 10 +/nDet/implant/setSegmentedLightGuide 16 16 5 50.8 50.8 45 45 G4_Pyrex_Glass + + +# Update the detector. +/nDet/implant/update +/nDet/implant/setReconLogic 1 + + +################ +# OUTPUT SETUP # +################ + +# Set the output filename prefix +/nDet/output/filename mtasImplant.root +/nDet/output/title SiPM array, Large MeV, 1 m from detector +#/nDet/output/index 69 +#/nDet/output/overwrite true +#/nDet/output/persistent true +#/nDet/output/enabled false +#/nDet/output/badEvents true +/nDet/output/debug true + +# Setup information about the PMT response +/nDet/output/trace/setRisetime 2 +/nDet/output/trace/setFalltime 20 +/nDet/output/trace/setTimeSpread 0.35 +/nDet/output/trace/setGain 1E4 +/nDet/output/trace/setBaseline 7.5 +/nDet/output/trace/setJitter 0.15 + +# Setup the PMT light pulse output +#/nDet/output/trace/enabled true +/nDet/output/trace/setTraceDelay 60 +/nDet/output/trace/setTraceLength 500 +/nDet/output/trace/setBitRange 16 +/nDet/output/trace/setGain 1000 +/nDet/output/trace/setCfdFraction 0.5 +/nDet/output/trace/setIntegralLow 5 +/nDet/output/trace/setIntegralHigh 10 + +################ +# SOURCE SETUP # +################ + +# Available source types: 137Cs 60Co 133Ba 241Am 90Sr 252Cf +#/nDet/source/type 252Cf + +#/nDet/source/type alpha 5 +/nDet/source/type electron 0.1 +/nDet/source/spot 10 #half-width for beam +/nDet/source/shape circle +#/nDet/source/beam 137Cs +#/nDet/source/beam gamma 0.03 + +#/nDet/source/spot 38.1 +#/nDet/source/spot 25.4 +#/nDet/source/spot 12.7 + +# Optical laser beam. +#/nDet/source/beam laser 360 +#/nDet/source/position 20 0 0 cm +#/nDet/source/direction 0 0 0 + +/nDet/source/iso 1 + +#/nDet/source/range 1.175 1.225 0 + +############### +# RUN CONTROL # +############### + +/run/beamOn 10000 diff --git a/mac/multi.mac b/mac/multi.mac new file mode 100644 index 0000000..9332b05 --- /dev/null +++ b/mac/multi.mac @@ -0,0 +1,155 @@ +# +# create empty scene +# + + +# Use a GDML file for the light guides. +# NOTE: This MUST be done BEFORE calling '/nDet/implant/update' +#/nDet/implant/loadGDML gdml/modifiedLightGuide.gdml +#/nDet/implant/loadGDML gdml/nonSegmentedLightGuide.gdml +#/nDet/implant/setTrapezoidLength 1.27 + +#/nDet/implant/setGDMLrotation 90 0 0 + +# This is important to set for GDML light-guide because +# we cannot obtain the information from the model itself. +/nDet/implant/setPmtDimensions 50.0 +/nDet/detector/setPmtDimensions 48.5 + +# Mylar and optical grease thickness. +/nDet/implant/setMylarThickness 0.025 +/nDet/implant/setGreaseThickness 0.1 +/nDet/detector/setMylarThickness 0.025 +/nDet/detector/setGreaseThickness 0.1 + +# Light diffuser. +#/nDet/implant/setDiffuserLength 0.5 + +# PMT segmentation. +/nDet/implant/setPmtColumns 8 +/nDet/implant/setPmtRows 8 +/nDet/detector/setPmtColumns 8 +/nDet/detector/setPmtRows 8 + +################## +# IMPLANT SETUP # +################## + +# Implant 2x2x10 in^3 +/nDet/implant/setDetectorLength 5.0 +/nDet/implant/setDetectorWidth 5.08 +/nDet/implant/setDetectorThickness 50.8 +/nDet/implant/setNumColumns 20 +/nDet/implant/setNumRows 20 +/nDet/implant/setStart 1 + +# Set the wrapping. +/nDet/implant/setWrapping mylar + +# Set the position and rotation of the detector in the lab frame. +/nDet/implant/setCylindrical 100 0 0 +/nDet/implant/setRotation 0 270 0 +/nDet/implant/addGeometry module + +# Load PSPMT gain matrix +# NOTE: This MUST be done AFTER calling '/nDet/implant/update' otherwise it will fail +#/nDet/implant/setGainMatrix gains/hamamatsuH12700A_LA0967.dat + +# Load PSPMT spectral response function +#/nDet/implant/setSpectralResponse spectral/hamamatsuH12700A.root + +################## +# DETECTOR SETUP # +################## + +# NEXT 2x2x10 in^3 +/nDet/detector/setDetectorLength 25.4 +/nDet/detector/setDetectorWidth 5.08 +/nDet/detector/setDetectorThickness 50.8 +/nDet/detector/setNumColumns 5 +/nDet/detector/setNumRows 5 + +# Set the wrapping. +/nDet/detector/setWrapping mylar + +# Set the position and rotation of the detector in the lab frame. +/nDet/detector/setCylindrical 100 0 6 +#/nDet/detector/setRotation 0 0 90 +/nDet/detector/addGeometry module + +# Update the implant. +/nDet/implant/update +# Update the detector. +/nDet/detector/update + +# Load PSPMT gain matrix +# NOTE: This MUST be done AFTER calling '/nDet/detector/update' otherwise it will fail +/nDet/detector/setGainMatrix gains/hamamatsuH12700A_LA0967.dat +/nDet/implant/setGainMatrix gains/hamamatsuH12700A_LA0967.dat + +# Load PSPMT spectral response function +/nDet/detector/setSpectralResponse spectral/hamamatsuH12700A.root +/nDet/implant/setSpectralResponse spectral/hamamatsuH12700A.root + +################ +# OUTPUT SETUP # +################ + +# Set the output filename prefix +/nDet/output/filename multi_test_1m.root +/nDet/output/title PSPMT_Next, 0.5 MeV, 1 m from detector +#/nDet/output/index 69 +#/nDet/output/overwrite true +#/nDet/output/persistent true +#/nDet/output/enabled false +#/nDet/output/badEvents true +/nDet/output/debug true + +# Setup information about the PMT response +/nDet/output/trace/setRisetime 2 +/nDet/output/trace/setFalltime 20 +/nDet/output/trace/setTimeSpread 0.35 +/nDet/output/trace/setGain 1E4 +/nDet/output/trace/setBaseline 7.5 +/nDet/output/trace/setJitter 0.15 + +# Setup the PMT light pulse output +#/nDet/output/trace/enabled true +/nDet/output/trace/setTraceDelay 60 +/nDet/output/trace/setTraceLength 500 +/nDet/output/trace/setBitRange 16 + +/nDet/output/trace/setCfdFraction 0.5 +/nDet/output/trace/setIntegralLow 5 +/nDet/output/trace/setIntegralHigh 10 + +################ +# SOURCE SETUP # +################ + +# Available source types: 137Cs 60Co 133Ba 241Am 90Sr 252Cf +#/nDet/source/type 252Cf + +/nDet/source/type gamma 1.0 +#/nDet/source/beam gamma 0.25 +#/nDet/source/beam 137Cs +#/nDet/source/beam gamma 0.03 + +#/nDet/source/spot 38.1 +#/nDet/source/spot 25.4 +#/nDet/source/spot 12.7 + +# Optical laser beam. +#/nDet/source/beam laser 360 +#/nDet/source/position 0.1 0 -13.5 cm +#/nDet/source/direction 0 0 0 + +/nDet/source/iso 1 + +#/nDet/source/range 1.175 1.225 0 + +############### +# RUN CONTROL # +############### + +#/run/beamOn 100 diff --git a/mac/next.mac b/mac/next.mac index b50b0c0..ba567a8 100644 --- a/mac/next.mac +++ b/mac/next.mac @@ -34,8 +34,8 @@ /nDet/detector/setDetectorLength 25.4 /nDet/detector/setDetectorWidth 5.08 /nDet/detector/setDetectorThickness 50.8 -/nDet/detector/setNumColumns 8 -/nDet/detector/setNumRows 4 +/nDet/detector/setNumColumns 5 +/nDet/detector/setNumRows 5 # NEXT 3x3x10 in^3 #/nDet/detector/setDetectorLength 25.4 @@ -123,4 +123,4 @@ # RUN CONTROL # ############### -#/run/beamOn 10000 +/run/beamOn 10 diff --git a/mac/pspmt.mac b/mac/pspmt.mac new file mode 100644 index 0000000..fa26752 --- /dev/null +++ b/mac/pspmt.mac @@ -0,0 +1,137 @@ +# +# create empty scene +# + + +# Use a GDML file for the light guides. +# NOTE: This MUST be done BEFORE calling '/nDet/implant/update' +#/nDet/implant/loadGDML gdml/modifiedLightGuide.gdml +#/nDet/implant/loadGDML gdml/nonSegmentedLightGuide.gdml +#/nDet/implant/setTrapezoidLength 1.27 + +#/nDet/implant/setGDMLrotation 90 0 0 + +# This is important to set for GDML light-guide because +# we cannot obtain the information from the model itself. +/nDet/implant/setPmtDimensions 50.0 + + +# Mylar and optical grease thickness. +/nDet/implant/setMylarThickness 0.025 +/nDet/implant/setGreaseThickness 0.5 + +# Light +/nDet/implant/setDiffuserLength 1.5 + +# Choose Scintillator +/nDet/implant/setMaterial yso + +# PMT segmentation. +/nDet/implant/setPmtColumns 8 +/nDet/implant/setPmtRows 8 + +################## +# DETECTOR SETUP # +################## + +# Pspmt +/nDet/implant/setDetectorLength 0.5 #in cm +#/nDet/implant/setDetectorWidth 5.08 +#/nDet/implant/setDetectorThickness 50.8 +/nDet/implant/setDetectorWidth 4. +/nDet/implant/setDetectorThickness 40. +/nDet/implant/setWindowThickness 1. +/nDet/implant/setNumColumns 8 +/nDet/implant/setNumRows 8 +/nDet/implant/setStart 1 + +# Set the wrapping. +/nDet/implant/setWrapping perfect + +# Load PSPMT gain matrix +# NOTE: This MUST be done AFTER calling '/nDet/implant/update' otherwise it will fail +#/nDet/implant/setGainMatrix ~/opt/NEXTSim/gain/hamamatsuH12700A_LA0967.dat +/nDet/implant/setGainMatrix hamamatsuH12700A_LA0967.dat +# Load PSPMT spectral response function +/nDet/implant/setSpectralResponse ~/opt/NEXTSim/spectral/hamamatsuH12700A.root + +# Set the position and rotation of the detector in the lab frame. +/nDet/implant/setPosition 0 0 0 cm +#/nDet/implant/setCylindrical 0.5 0 0 +/nDet/implant/setRotation 0 270 0 +/nDet/implant/addGeometry module + +/nDet/implant/addDiffuserLayer 50 50 0.1 +#/nDet/implant/addLightGuide 50 50 50 50 5 +#/nDet/segLightGuide/thickness 10 +#/nDet/implant/setSegmentedLightGuide 24 24 5 50.8 50.8 45 45 G4_Pyrex_Glass + + +# Update the detector. +/nDet/implant/update + + +################ +# OUTPUT SETUP # +################ + +# Set the output filename prefix +/nDet/output/filename posTestYSOPerfect90Sr.root +/nDet/output/title PSPMT, 0.5 MeV, 1 m from detector +#/nDet/output/index 69 +#/nDet/output/overwrite true +#/nDet/output/persistent true +#/nDet/output/enabled false +#/nDet/output/badEvents true +/nDet/output/debug true + +# Setup information about the PMT response +/nDet/output/trace/setRisetime 2 +/nDet/output/trace/setFalltime 20 +/nDet/output/trace/setTimeSpread 0.35 +/nDet/output/trace/setGain 1E4 +/nDet/output/trace/setBaseline 7.5 +/nDet/output/trace/setJitter 0.15 + +# Setup the PMT light pulse output +#/nDet/output/trace/enabled true +/nDet/output/trace/setTraceDelay 60 +/nDet/output/trace/setTraceLength 500 +/nDet/output/trace/setBitRange 16 +/nDet/output/trace/setGain 1000 +/nDet/output/trace/setCfdFraction 0.5 +/nDet/output/trace/setIntegralLow 5 +/nDet/output/trace/setIntegralHigh 10 + +################ +# SOURCE SETUP # +################ + +# Available source types: 137Cs 60Co 133Ba 241Am 90Sr 252Cf +#/nDet/source/type 252Cf + +#/nDet/source/type alpha 5 +/nDet/source/type 90Sr +#/nDet/source/spot 5 #half-width for beam +#/nDet/source/shape circle +#/nDet/source/beam 137Cs +#/nDet/source/beam gamma 0.03 + +#/nDet/source/spot 38.1 +#/nDet/source/spot 25.4 +#/nDet/source/spot 12.7 + +# Optical laser beam. +#/nDet/source/beam laser 360 +#/nDet/source/position 20 0 0 cm +#/nDet/source/direction 0 0 0 + +/nDet/source/iso 1 + +#/nDet/source/range 1.175 1.225 0 + +############### +# RUN CONTROL # +############### + +#/run/beamOn 200000 diff --git a/mac/pspmt1inLG.mac b/mac/pspmt1inLG.mac new file mode 100644 index 0000000..d4f83a6 --- /dev/null +++ b/mac/pspmt1inLG.mac @@ -0,0 +1,142 @@ +# +# create empty scene +# + + +# Use a GDML file for the light guides. +# NOTE: This MUST be done BEFORE calling '/nDet/implant/update' +#/nDet/implant/loadGDML gdml/modifiedLightGuide.gdml +#/nDet/implant/loadGDML gdml/nonSegmentedLightGuide.gdml +#/nDet/implant/setTrapezoidLength 1.27 + +#/nDet/implant/setGDMLrotation 90 0 0 + +# This is important to set for GDML light-guide because +# we cannot obtain the information from the model itself. +/nDet/implant/setPmtDimensions 25.0 + + +# Mylar and optical grease thickness. +/nDet/implant/setMylarThickness 0.025 +/nDet/implant/setGreaseThickness 0.3 + +# Light +/nDet/implant/setDiffuserLength 1.5 + +# Choose Scintillator +/nDet/implant/setMaterial yso + +# PMT segmentation. +/nDet/implant/setPmtColumns 8 +/nDet/implant/setPmtRows 8 + +################## +# DETECTOR SETUP # +################## + +# NEXT 2x2x10 in^3 +/nDet/implant/setDetectorLength 1 +/nDet/implant/setDetectorWidth 5.08 +/nDet/implant/setDetectorThickness 50.8 +/nDet/implant/setWindowThickness 1. +/nDet/implant/setNumColumns 24 +/nDet/implant/setNumRows 24 +/nDet/implant/setStart 1 + +# NEXT 3x3x10 in^3 +#/nDet/implant/setDetectorLength 5.4 +#/nDet/implant/setDetectorWidth 7.62 +#/nDet/implant/setDetectorThickness 76.2 +#/nDet/implant/setNumColumns 12 +#/nDet/implant/setNumRows 6 + +# Set the wrapping. +/nDet/implant/setWrapping mylar + +# Load PSPMT gain matrix +# NOTE: This MUST be done AFTER calling '/nDet/implant/update' otherwise it will fail +#/nDet/implant/setGainMatrix ~/opt/NEXTSim/gain/hamamatsuH12700A_LA0967.dat +/nDet/implant/setGainMatrix hamamatsuH12700A_LA0967.dat +# Load PSPMT spectral response function +/nDet/implant/setSpectralResponse ~/opt/NEXTSim/spectral/hamamatsuH12700A.root + +# Set the position and rotation of the detector in the lab frame. +/nDet/implant/setPosition 0 0 0 cm +#/nDet/implant/setCylindrical 0.5 0 0 +/nDet/implant/setRotation 0 270 0 +/nDet/implant/addGeometry module + +#/nDet/implant/addLightGuide 50 50 50 50 5 +#/nDet/segLightGuide/thickness 10 +/nDet/implant/setSegmentedLightGuide 24 24 5 50 50 25 25 G4_Pyrex_Glass +/nDet/implant/addDiffuserLayer 25 25 1 + + +# Update the detector. +/nDet/implant/update + + +################ +# OUTPUT SETUP # +################ + +# Set the output filename prefix +/nDet/output/filename ysoMylarSmallPMT90Sr.root +/nDet/output/title PSPMT, 0.5 MeV, 1 m from detector +#/nDet/output/index 69 +#/nDet/output/overwrite true +#/nDet/output/persistent true +#/nDet/output/enabled false +#/nDet/output/badEvents true +/nDet/output/debug true + +# Setup information about the PMT response +/nDet/output/trace/setRisetime 2 +/nDet/output/trace/setFalltime 20 +/nDet/output/trace/setTimeSpread 0.35 +/nDet/output/trace/setGain 1E4 +/nDet/output/trace/setBaseline 7.5 +/nDet/output/trace/setJitter 0.15 + +# Setup the PMT light pulse output +#/nDet/output/trace/enabled true +/nDet/output/trace/setTraceDelay 60 +/nDet/output/trace/setTraceLength 500 +/nDet/output/trace/setBitRange 16 +/nDet/output/trace/setGain 1000 +/nDet/output/trace/setCfdFraction 0.5 +/nDet/output/trace/setIntegralLow 5 +/nDet/output/trace/setIntegralHigh 10 + +################ +# SOURCE SETUP # +################ + +# Available source types: 137Cs 60Co 133Ba 241Am 90Sr 252Cf +#/nDet/source/type 252Cf + +#/nDet/source/type alpha 5 +/nDet/source/type 90Sr +/nDet/source/spot 25 #half-width for beam +/nDet/source/shape square +#/nDet/source/beam 137Cs +#/nDet/source/beam gamma 0.03 + +#/nDet/source/spot 38.1 +#/nDet/source/spot 25.4 +#/nDet/source/spot 12.7 + +# Optical laser beam. +#/nDet/source/beam laser 360 +#/nDet/source/position 20 0 0 cm +#/nDet/source/direction 0 0 0 + +/nDet/source/iso 1 + +#/nDet/source/range 1.175 1.225 0 + +############### +# RUN CONTROL # +############### + +#/run/beamOn 3000000 diff --git a/mac/ribf168.mac b/mac/ribf168.mac new file mode 100644 index 0000000..70fe0eb --- /dev/null +++ b/mac/ribf168.mac @@ -0,0 +1,112 @@ +# hagrid.mac +# Cory R Thornsberry +# Simulates an elliptical bar (football) with a 1 MeV beam of neutrons + +/nDet/implant/setPmtDimensions 50.4 + +# Mylar and optical grease thickness. +/nDet/implant/setMylarThickness 0.025 +/nDet/implant/setGreaseThickness 0.1 + +################ +# OUTPUT SETUP # +################ + +# Set the output filename prefix +/nDet/output/filename ribf168EfficencyTests.root +/nDet/output/title ribf168 exp setup with ~16 Hagrid and Pspmt implant and 0.4 MeV gamma circle beam w 5 mm rad +/nDet/output/debug false + +# Setup information about the PMT response +/nDet/output/trace/setRisetime 2 +/nDet/output/trace/setFalltime 20 +/nDet/output/trace/setTimeSpread 0.35 +/nDet/output/trace/setGain 2E4 +/nDet/output/trace/setBaseline 7.5 +/nDet/output/trace/setJitter 0.15 + +# Setup the PMT light pulse output +/nDet/output/trace/setTraceDelay 60 +/nDet/output/trace/setTraceLength 500 +/nDet/output/trace/setBitRange 16 + +/nDet/output/trace/setCfdFraction 0.5 +/nDet/output/trace/setIntegralLow 5 + +################## +# IMPLANT SETUP # +################## + +# IMPLANT Setup +/nDet/implant/setMaterial yso +# 5 mm thick scintillator +/nDet/implant/setDetectorLength 0.5 +/nDet/implant/setDetectorWidth 5.08 +/nDet/implant/setDetectorThickness 50.8 +/nDet/implant/setWindowThickness 1. +/nDet/implant/setNumColumns 24 +/nDet/implant/setNumRows 24 +#/nDet/implant/setStart 1 + +# Set the wrapping. +/nDet/implant/setWrapping perfect + +# Load PSPMT gain matrix +# NOTE: This MUST be done AFTER calling '/nDet/implant/update' otherwise it will fail +#/nDet/implant/setGainMatrix ~/opt/NEXTSim/gain/hamamatsuH12700A_LA0967.dat +/nDet/implant/setGainMatrix hamamatsuH12700A_LA0967.dat +# Load PSPMT spectral response function +/nDet/implant/setSpectralResponse ~/opt/NEXTSim/spectral/hamamatsuH12700A.root + +# Set the position and rotation of the detector in the lab frame. +/nDet/implant/setPosition 0 0 0 cm +#/nDet/implant/setCylindrical 0.5 0 0 +/nDet/implant/setRotation 0 270 0 +/nDet/implant/addGeometry module + +/nDet/implant/addDiffuserLayer 50 50 0.1 +#/nDet/implant/addLightGuide 50 50 50 50 5 +#/nDet/segLightGuide/thickness 10 +/nDet/implant/setSegmentedLightGuide 24 24 5 50.8 50.8 45 45 G4_Pyrex_Glass + + +# Update the detector. +/nDet/implant/update +/nDet/output/trace/setIntegralHigh 10 + +################## +# HAGRID SETUP # +################## + +#### Aluminum case thickness set to 0.305 cm + +# Ellipse prototype +/nDet/implant/setMaterial labr3 +/nDet/implant/setDetectorLength 5.08 cm +/nDet/implant/setDetectorWidth 5.08 cm +/nDet/implant/setMylarThickness 3.05 mm +/nDet/implant/setWrapping aluminum + +## Update the detector. +/nDet/implant/addArray hagrid 5.7 0 180 16 +/nDet/implant/update + +################ +# SOURCE SETUP # +################ + +# Available source types: 137Cs 60Co 133Ba 241Am 90Sr 252Cf +#/nDet/source/type 60Co + +/nDet/source/type gamma 0.4 +/nDet/source/spot 5 mm +/nDet/source/shape circle + +# Set isotropic source (0=off, 1=psuedo, 2=realistic) +/nDet/source/iso 2 + +############### +# RUN CONTROL # +############### + +/run/beamOn 1000000 diff --git a/mac/thintest.mac b/mac/thintest.mac new file mode 100644 index 0000000..4a39229 --- /dev/null +++ b/mac/thintest.mac @@ -0,0 +1,114 @@ +# hagrid.mac +# Cory R Thornsberry +# Simulates an elliptical bar (football) with a 1 MeV beam of neutrons + +/nDet/implant/setPmtDimensions 50.4 + +# Mylar and optical grease thickness. +/nDet/implant/setMylarThickness 0.025 +/nDet/implant/setGreaseThickness 0.1 + +################ +# OUTPUT SETUP # +################ + +# Set the output filename prefix +/nDet/output/filename thinTests.root +/nDet/output/title ribf168 exp setup with ~16 Hagrid and Pspmt implant and 1. MeV gamma circle beam w 5 mm rad no seg +/nDet/output/debug false + +# Setup information about the PMT response +/nDet/output/trace/setRisetime 2 +/nDet/output/trace/setFalltime 20 +/nDet/output/trace/setTimeSpread 0.35 +/nDet/output/trace/setGain 2E4 +/nDet/output/trace/setBaseline 7.5 +/nDet/output/trace/setJitter 0.15 + +# Setup the PMT light pulse output +/nDet/output/trace/setTraceDelay 60 +/nDet/output/trace/setTraceLength 500 +/nDet/output/trace/setBitRange 16 + +/nDet/output/trace/setCfdFraction 0.5 +/nDet/output/trace/setIntegralLow 5 + +################## +# IMPLANT SETUP # +################## + +# IMPLANT Setup +/nDet/implant/setMaterial yso +# 5 mm thick scintillator +/nDet/implant/setDetectorLength 0.5 +/nDet/implant/setDetectorWidth 5.08 +/nDet/implant/setDetectorThickness 50.8 +/nDet/implant/setWindowThickness 1. +/nDet/implant/setNumColumns 1 +/nDet/implant/setNumRows 1 +#/nDet/implant/setNumColumns 24 +#/nDet/implant/setNumRows 24 +#/nDet/implant/setStart 1 + +# Set the wrapping. +/nDet/implant/setWrapping perfect + +# Load PSPMT gain matrix +# NOTE: This MUST be done AFTER calling '/nDet/implant/update' otherwise it will fail +#/nDet/implant/setGainMatrix ~/opt/NEXTSim/gain/hamamatsuH12700A_LA0967.dat +/nDet/implant/setGainMatrix hamamatsuH12700A_LA0967.dat +# Load PSPMT spectral response function +/nDet/implant/setSpectralResponse ~/opt/NEXTSim/spectral/hamamatsuH12700A.root + +# Set the position and rotation of the detector in the lab frame. +/nDet/implant/setPosition 0 0 0 cm +#/nDet/implant/setCylindrical 0.5 0 0 +/nDet/implant/setRotation 0 270 0 +/nDet/implant/addGeometry module + +/nDet/implant/addDiffuserLayer 50 50 0.1 +#/nDet/implant/addLightGuide 50 50 50 50 5 +#/nDet/segLightGuide/thickness 10 +#/nDet/implant/setSegmentedLightGuide 24 24 5 50.8 50.8 45 45 G4_Pyrex_Glass + + +# Update the detector. +/nDet/implant/update +/nDet/output/trace/setIntegralHigh 10 + +################## +# HAGRID SETUP # +################## + +#### Aluminum case thickness set to 0.305 cm + +# Ellipse prototype +/nDet/implant/setMaterial labr3 +/nDet/implant/setDetectorLength 5.08 cm +/nDet/implant/setDetectorWidth 5.08 cm +/nDet/implant/setMylarThickness 3.05 mm +/nDet/implant/setWrapping aluminum + +## Update the detector. +/nDet/implant/addArray hagrid 5.7 0 180 16 +/nDet/implant/update + +################ +# SOURCE SETUP # +################ + +# Available source types: 137Cs 60Co 133Ba 241Am 90Sr 252Cf +#/nDet/source/type 60Co + +/nDet/source/type gamma 1. +/nDet/source/spot 5 mm +/nDet/source/shape circle + +# Set isotropic source (0=off, 1=psuedo, 2=realistic) +/nDet/source/iso 2 + +############### +# RUN CONTROL # +############### + +#/run/beamOn 1000000 diff --git a/source/CERNSupport.cc b/source/CERNSupport.cc index 7d83471..8153466 100644 --- a/source/CERNSupport.cc +++ b/source/CERNSupport.cc @@ -89,11 +89,11 @@ void CERNSupport::Place(G4RotationMatrix *pRot, 0, 0 ); //G4ThreeVector offset = G4ThreeVector(0, 0, 0); - std::string file1 = "/home/jheidema/opt/NEXTSim/STL_export/VerticalFrame.stl"; + std::string file1 = "/ARCHIVE/Ddata/geant4_stl/vandle/isolde/VerticalFrame.stl"; CADMesh * rebMesh = new CADMesh((char*)file1.c_str()); rebMesh->SetScale(cm); - //CADMesh* rebMesh = new CADMesh("/home/jheidema/opt/NEXTSim/STL_export/VerticalFrame.stl", cm, offset, false); + //CADMesh* rebMesh = new CADMesh("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/VerticalFrame.stl", cm, offset, false); G4VSolid* ribSolid = rebMesh->TessellatedMesh(); G4LogicalVolume* ribLogic = new G4LogicalVolume(ribSolid, frameMaterial, "CERNRrameRib"); ribLogic->SetVisAttributes(argSupportVisAtt); diff --git a/source/CloverQuadBuchDetector.cc b/source/CloverQuadBuchDetector.cc index 154191e..734a35e 100644 --- a/source/CloverQuadBuchDetector.cc +++ b/source/CloverQuadBuchDetector.cc @@ -74,7 +74,7 @@ G4VPhysicalVolume* CloverQuadBuchDetector::Construct() // Detector Construction // // Meshing - mesh_Capsule = new CADMesh(const_cast("/home/jheidema/opt/NEXTSim/STL_export/Clover_Bucharest_RefFace/Clover_Assembly_Bucharest_RefModif_Capsule_Bucharest_redesigned_1.stl"), mm, G4ThreeVector( 0*cm, 0*cm, 0*cm), false); + mesh_Capsule = new CADMesh(const_cast("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/Clover_Bucharest_RefFace/Clover_Assembly_Bucharest_RefModif_Capsule_Bucharest_redesigned_1.stl"), mm, G4ThreeVector( 0*cm, 0*cm, 0*cm), false); Capsule_sol = mesh_Capsule->TessellatedMesh(); // Logical Volume diff --git a/source/CloverQuadDetector.cc b/source/CloverQuadDetector.cc index ffbcfb1..4410033 100644 --- a/source/CloverQuadDetector.cc +++ b/source/CloverQuadDetector.cc @@ -90,9 +90,9 @@ G4VPhysicalVolume* CloverQuadDetector::Construct() // // Meshing - mesh_Capsule = new CADMesh(const_cast("/home/jheidema/opt/NEXTSim/STL_export/Clover_KULeuven_RefFace/Clover_Assembly_RefModif_capsule2_1.stl"), mm, G4ThreeVector(0*cm, 0*cm, 0*cm), false); // back to 08122015 - mesh_CapsuleCap = new CADMesh(const_cast("/home/jheidema/opt/NEXTSim/STL_export/Clover_KULeuven_RefFace/Clover_Assembly_RefModif_Capsule_cap_2.stl"), mm, G4ThreeVector(0*cm, 0*cm, 0*cm), false); // back to 08122015 - mesh_CarboneWindow = new CADMesh(const_cast("/home/jheidema/opt/NEXTSim/STL_export/Clover_KULeuven_RefFace/Clover_Assembly_RefModif_Carbone_window_3.stl"), mm, G4ThreeVector(0*cm, 0*cm, 0*cm), false); // back to 08122015 + mesh_Capsule = new CADMesh(const_cast("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/Clover_KULeuven_RefFace/Clover_Assembly_RefModif_capsule2_1.stl"), mm, G4ThreeVector(0*cm, 0*cm, 0*cm), false); // back to 08122015 + mesh_CapsuleCap = new CADMesh(const_cast("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/Clover_KULeuven_RefFace/Clover_Assembly_RefModif_Capsule_cap_2.stl"), mm, G4ThreeVector(0*cm, 0*cm, 0*cm), false); // back to 08122015 + mesh_CarboneWindow = new CADMesh(const_cast("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/Clover_KULeuven_RefFace/Clover_Assembly_RefModif_Carbone_window_3.stl"), mm, G4ThreeVector(0*cm, 0*cm, 0*cm), false); // back to 08122015 diff --git a/source/CloverSingleBuchDetector.cc b/source/CloverSingleBuchDetector.cc index 5ade28b..f5d29df 100644 --- a/source/CloverSingleBuchDetector.cc +++ b/source/CloverSingleBuchDetector.cc @@ -46,8 +46,8 @@ G4VPhysicalVolume* CloverSingleBuchDetector::Construct() // Detector Construction // // Meshing - mesh_CloverSingle = new CADMesh(const_cast(Form("/home/jheidema/opt/NEXTSim/STL_export/Clover_Bucharest_RefFace/Clover_Assembly_Bucharest_RefModif_Crystal2_%i.stl",cr_nb+2)), mm, G4ThreeVector( 0*cm, 0*cm, 0*cm), false); - //G4cout << Form("/home/jheidema/opt/NEXTSim/STL_export/Clover_Bucharest_RefFace/Clover_Assembly_Bucharest_RefModif_Crystal2_%i.stl",cr_nb+1) << G4endl; + mesh_CloverSingle = new CADMesh(const_cast(Form("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/Clover_Bucharest_RefFace/Clover_Assembly_Bucharest_RefModif_Crystal2_%i.stl",cr_nb+2)), mm, G4ThreeVector( 0*cm, 0*cm, 0*cm), false); + //G4cout << Form("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/Clover_Bucharest_RefFace/Clover_Assembly_Bucharest_RefModif_Crystal2_%i.stl",cr_nb+1) << G4endl; CloverSingle_sol = mesh_CloverSingle->TessellatedMesh(); CloverSingle_log = new G4LogicalVolume(CloverSingle_sol, HPGe, Form("/Clover%i_Crystal%i_Buch_log",cl_nb ,cr_nb)); CloverSingle_log -> SetVisAttributes(det_vis_att); diff --git a/source/CloverSingleDetector.cc b/source/CloverSingleDetector.cc index a30f2ff..9dada15 100644 --- a/source/CloverSingleDetector.cc +++ b/source/CloverSingleDetector.cc @@ -46,8 +46,8 @@ G4VPhysicalVolume* CloverSingleDetector::Construct() // // Meshing // 18022015 mesh_CloverSingle = new CADMesh(const_cast(Form("../STL_export/Clover_KULeuven/Clover_Assembly_Crystal2_%i.stl",cr_nb+4)), mm, G4ThreeVector(-0.2524*cm + 75*mm), false); - mesh_CloverSingle = new CADMesh(const_cast(Form("/home/jheidema/opt/NEXTSim/STL_export/Clover_KULeuven_RefFace/Clover_Assembly_RefModif_Crystal2_%i.stl",cr_nb+4)), mm, G4ThreeVector(0*cm, 0*cm, 0*cm), false); // back to 08122015 - //G4cout << Form("/home/jheidema/opt/NEXTSim/STL_export/Clover_KULeuven_RefFace/Clover_Assembly_RefModif_Crystal2_%i.stl",cr_nb+4) << G4endl; + mesh_CloverSingle = new CADMesh(const_cast(Form("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/Clover_KULeuven_RefFace/Clover_Assembly_RefModif_Crystal2_%i.stl",cr_nb+4)), mm, G4ThreeVector(0*cm, 0*cm, 0*cm), false); // back to 08122015 + //G4cout << Form("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/Clover_KULeuven_RefFace/Clover_Assembly_RefModif_Crystal2_%i.stl",cr_nb+4) << G4endl; CloverSingle_sol = mesh_CloverSingle->TessellatedMesh(); CloverSingle_log = new G4LogicalVolume(CloverSingle_sol, HPGe, Form("/Clover%i_Crystal%i_log",cl_nb ,cr_nb)); CloverSingle_log -> SetVisAttributes(det_vis_att); diff --git a/source/IS530_Chamber.cc b/source/IS530_Chamber.cc index 9a1af45..0b26a2c 100644 --- a/source/IS530_Chamber.cc +++ b/source/IS530_Chamber.cc @@ -108,8 +108,8 @@ G4VPhysicalVolume* IS530_Chamber::Construct() // Detector Construction // vector IS530_Chamber_name; - IS530_Chamber_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/Bucharest_Chamber/Bucharest_Chamber_IS530_capac_leon.stl"); - IS530_Chamber_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/Bucharest_Chamber/Bucharest_Chamber_IS530_incinta_leon.stl"); + IS530_Chamber_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/Bucharest_Chamber/Bucharest_Chamber_IS530_capac_leon.stl"); + IS530_Chamber_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/Bucharest_Chamber/Bucharest_Chamber_IS530_incinta_leon.stl"); // Meshing and Logical Volumes for(int i = 0; i IS530_Plastic_name; - IS530_Plastic_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/Bucharest_Plastic/Bucharest_Plastic.stl"); - //IS530_Plastic_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/Bucharest_Plastic/Bucharest_Plastic_back.stl"); - IS530_Plastic_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/Bucharest_Plastic/Bucharest_Plastic_holders.stl"); - IS530_Plastic_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/Bucharest_Plastic/Tape.stl"); + IS530_Plastic_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/Bucharest_Plastic/Bucharest_Plastic.stl"); + //IS530_Plastic_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/Bucharest_Plastic/Bucharest_Plastic_back.stl"); + IS530_Plastic_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/Bucharest_Plastic/Bucharest_Plastic_holders.stl"); + IS530_Plastic_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/Bucharest_Plastic/Tape.stl"); // Meshing and Logical Volumes for(int i = 0; i Polyhedron_name; /* */ - Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_hexagon_64.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_hexagon_65.stl"); - Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_hexagon_66.stl"); - Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_hexagon_70.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_hexagon_71.stl"); - //Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_hexagon_72.stl"); + Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_hexagon_64.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_hexagon_65.stl"); + Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_hexagon_66.stl"); + Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_hexagon_70.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_hexagon_71.stl"); + //Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_hexagon_72.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_hexagon_74.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_hexagon_75.stl"); - Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_hexagon_76.stl"); - Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_hexagon_79.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_hexagon_74.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_hexagon_75.stl"); + Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_hexagon_76.stl"); + Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_hexagon_79.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_hexagon_80.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_hexagon_81.stl"); - //Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_hexagon_82.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_hexagon_80.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_hexagon_81.stl"); + //Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_hexagon_82.stl"); - Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_hexagon_83.stl"); + Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_hexagon_83.stl"); //************************************** @@ -125,144 +125,144 @@ G4VPhysicalVolume* Polyhedron::Construct() -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_hexagon_85.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_hexagon_89.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_hexagon_91.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_hexagon_92.stl"); - Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_octogon_66.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_octogon_67.stl"); - Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_octogon_69.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_octogon_70.stl"); - Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_octogon_73.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_octogon_74.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_octogon_76.stl"); - Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_octogon_77.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_octogon_78.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_octogon_79.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_octogon_83.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_octogon_87.stl"); - Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_octogon_88.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_octogon_97.stl"); - Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_patrat_63.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_patrat_64.stl"); - Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_patrat_67.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_patrat_68.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_patrat_69.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_patrat_72.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_patrat_73.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_patrat_74.stl"); - Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_patrat_75.stl"); - Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_patrat_76.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_patrat_77.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_hexagon_85.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_hexagon_89.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_hexagon_91.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_hexagon_92.stl"); + Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_octogon_66.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_octogon_67.stl"); + Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_octogon_69.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_octogon_70.stl"); + Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_octogon_73.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_octogon_74.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_octogon_76.stl"); + Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_octogon_77.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_octogon_78.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_octogon_79.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_octogon_83.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_octogon_87.stl"); + Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_octogon_88.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_octogon_97.stl"); + Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_patrat_63.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_patrat_64.stl"); + Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_patrat_67.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_patrat_68.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_patrat_69.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_patrat_72.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_patrat_73.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_patrat_74.stl"); + Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_patrat_75.stl"); + Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_patrat_76.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_patrat_77.stl"); //**************************************************************** - //Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_patrat_78.stl"); - Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_patrat_79.stl"); - //Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_patrat_80.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_patrat_81.stl"); - //Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_patrat_82.stl"); - Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_patrat_83.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_patrat_84.stl"); - Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_patrat_85.stl"); - //Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_patrat_86.stl"); - Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_patrat_87.stl"); + //Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_patrat_78.stl"); + Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_patrat_79.stl"); + //Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_patrat_80.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_patrat_81.stl"); + //Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_patrat_82.stl"); + Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_patrat_83.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_patrat_84.stl"); + Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_patrat_85.stl"); + //Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_patrat_86.stl"); + Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_patrat_87.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_patrat_88.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_patrat_90.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_patrat_93.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_patrat_94.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_patrat_95.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_patrat_96.stl"); - //Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_capac_circular_100.stl"); - // Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_capac_circular_101.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_patrat_88.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_patrat_90.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_patrat_93.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_patrat_94.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_patrat_95.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_patrat_96.stl"); + //Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_capac_circular_100.stl"); + // Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_capac_circular_101.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_capac_circular_102.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_capac_circular_103.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_capac_circular_104.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_capac_circular_105.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_capac_circular_88.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_capac_circular_89.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_capac_circular_90.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_capac_circular_91.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_capac_circular_92.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_capac_circular_102.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_capac_circular_103.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_capac_circular_104.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_capac_circular_105.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_capac_circular_88.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_capac_circular_89.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_capac_circular_90.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_capac_circular_91.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_capac_circular_92.stl"); //front cap - //Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_capac_circular_93.stl"); - Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_capac_circular_94.stl"); - Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_capac_circular_95.stl"); - Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_capac_circular_96.stl"); + //Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_capac_circular_93.stl"); + Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_capac_circular_94.stl"); + Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_capac_circular_95.stl"); + Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_capac_circular_96.stl"); - Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_capac_circular_98.stl"); + Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_capac_circular_98.stl"); //front cap - //Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_capac_circular_99.stl"); + //Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_capac_circular_99.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_flansa_prindere_detector_patrat_103.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_flansa_prindere_detector_patrat_104.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_flansa_prindere_detector_patrat_107.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_flansa_prindere_detector_patrat_109.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_flansa_prindere_detector_patrat_110.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_flansa_prindere_detector_patrat_113.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_flansa_prindere_detector_patrat_119.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_flansa_prindere_detector_patrat_131.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_flansa_prindere_detector_patrat_132.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_flansa_prindere_detector_patrat_141.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_flansa_prindere_detector_patrat_97.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_flansa_prindere_detector_patrat_98.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_flansa_intermediara_detector_patrat_102.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_flansa_intermediara_detector_patrat_103.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_flansa_intermediara_detector_patrat_106.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_flansa_intermediara_detector_patrat_108.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_flansa_intermediara_detector_patrat_109.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_flansa_intermediara_detector_patrat_112.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_flansa_intermediara_detector_patrat_118.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_flansa_intermediara_detector_patrat_130.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_flansa_intermediara_detector_patrat_131.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_flansa_intermediara_detector_patrat_140.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_flansa_intermediara_detector_patrat_96.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_flansa_intermediara_detector_patrat_97.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_flansa_prindere_detector_patrat_103.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_flansa_prindere_detector_patrat_104.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_flansa_prindere_detector_patrat_107.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_flansa_prindere_detector_patrat_109.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_flansa_prindere_detector_patrat_110.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_flansa_prindere_detector_patrat_113.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_flansa_prindere_detector_patrat_119.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_flansa_prindere_detector_patrat_131.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_flansa_prindere_detector_patrat_132.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_flansa_prindere_detector_patrat_141.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_flansa_prindere_detector_patrat_97.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_flansa_prindere_detector_patrat_98.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_flansa_intermediara_detector_patrat_102.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_flansa_intermediara_detector_patrat_103.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_flansa_intermediara_detector_patrat_106.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_flansa_intermediara_detector_patrat_108.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_flansa_intermediara_detector_patrat_109.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_flansa_intermediara_detector_patrat_112.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_flansa_intermediara_detector_patrat_118.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_flansa_intermediara_detector_patrat_130.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_flansa_intermediara_detector_patrat_131.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_flansa_intermediara_detector_patrat_140.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_flansa_intermediara_detector_patrat_96.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_flansa_intermediara_detector_patrat_97.stl"); - Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_flansa_fixa_pe_prisma_2_114.stl"); + Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_flansa_fixa_pe_prisma_2_114.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_flansa_fixa_pe_prisma_2_115.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_flansa_fixa_pe_prisma_2_115.stl"); - Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_flansa_fixa_pe_prisma_2_118.stl"); + Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_flansa_fixa_pe_prisma_2_118.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_flansa_fixa_pe_prisma_2_119.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_flansa_fixa_pe_prisma_2_122.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_flansa_fixa_pe_prisma_2_123.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_flansa_fixa_pe_prisma_2_124.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_flansa_fixa_pe_prisma_2_126.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_flansa_fixa_pe_prisma_2_127.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_flansa_fixa_pe_prisma_2_128.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_flansa_fixa_pe_prisma_2_119.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_flansa_fixa_pe_prisma_2_122.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_flansa_fixa_pe_prisma_2_123.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_flansa_fixa_pe_prisma_2_124.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_flansa_fixa_pe_prisma_2_126.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_flansa_fixa_pe_prisma_2_127.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_flansa_fixa_pe_prisma_2_128.stl"); //pices around Ge - Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_flansa_fixa_pe_prisma_2_132.stl"); - Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_flansa_fixa_pe_prisma_2_136.stl"); + Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_flansa_fixa_pe_prisma_2_132.stl"); + Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_flansa_fixa_pe_prisma_2_136.stl"); @@ -270,30 +270,30 @@ G4VPhysicalVolume* Polyhedron::Construct() -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_talpa1_28.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_talpa_23.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_talpa_53.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_talpa1_28.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_talpa_23.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_talpa_53.stl"); - Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_Placa_suport_polietru1_4.stl"); + Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_Placa_suport_polietru1_4.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_disc_5.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_disc_7.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/IDS_5_disc_9.stl"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/"); -// Polyhedron_name.push_back("/home/jheidema/opt/NEXTSim/STL_export/IDS_5/"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_disc_5.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_disc_7.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/IDS_5_disc_9.stl"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/"); +// Polyhedron_name.push_back("/ARCHIVE/Ddata/geant4_stl/vandle/isolde/IDS_5/"); // Meshing and Logical Volumes for(int i = 0; i 0 ? Ncol : 1); @@ -112,7 +134,8 @@ void centerOfMass::setSegmentedPmt(const nDetDetectorParams *params){ // Setup the anode gain matrix. gainMatrix.clear(); - countMatrix.clear(); + // std::cout<<"Clearing count matrix"<(Nrow, 100)); countMatrix.push_back(std::vector(Nrow, 0)); @@ -124,10 +147,10 @@ bool centerOfMass::loadSpectralResponse(const char *fname){ } bool centerOfMass::loadGainMatrix(const char *fname){ - if(gainMatrix.empty() || Ncol*Nrow == 0) return false; - std::ifstream gainFile(fname); - if(!gainFile.good()) return false; - + if(gainMatrix.empty() || Ncol*Nrow == 0) {/*std::cout<<"Gain Matrix Empty"<(Nrow, 0)); } } @@ -202,15 +224,13 @@ bool centerOfMass::addPoint(const double &energy, const double &time, const G4Th increment(xpos, ypos); // Add the anger logic currents to the anode outputs. - double totalCurrent = 0; double *current = getCurrent(xpos, ypos); if(current){ for(size_t i = 0; i < 4; i++){ anodeCurrent[i] += gain*mass*current[i]; - totalCurrent += current[i]; } for(size_t i = 0; i < 4; i++){ - anodeResponse[i].addPhoton(time, 0, gain*mass*(current[i]/totalCurrent)); + anodeResponse[i].addPhoton(time, 0, gain*mass*(current[i])); } } @@ -233,7 +253,7 @@ bool centerOfMass::addPoint(const double &energy, const double &time, const G4Th response.addPhoton(time, wavelength, gain); // Add the "mass" to the others weighted by the individual anode gain - center += pos; + center += pos; //add pos calculated based on anode current totalMass += mass; } } diff --git a/source/nDetConstruction.cc b/source/nDetConstruction.cc index ea355df..beb1ce5 100644 --- a/source/nDetConstruction.cc +++ b/source/nDetConstruction.cc @@ -38,6 +38,7 @@ nDetConstruction &nDetConstruction::getInstance(){ nDetConstruction::nDetConstruction(){ currentDetector = NULL; + currentImplant = NULL; fDetectorMessenger = new nDetConstructionMessenger(this); @@ -57,8 +58,10 @@ nDetConstruction::~nDetConstruction(){ } G4VPhysicalVolume* nDetConstruction::Construct(){ - if(!expHall->getPhysicalVolume()) + if(!expHall->getPhysicalVolume()){ this->ConstructDetector(); + this->ConstructImplant(); + } return expHall->getPhysicalVolume(); } @@ -70,14 +73,44 @@ G4VPhysicalVolume* nDetConstruction::ConstructDetector(){ // Build experiment hall. expHall->buildExpHall(&materials); - // Place all detectors. for(auto det : userDetectors){ currentDetector = det; - // Build the detector det->construct(); + // Place all detectors. + det->placeDetector(expHall->getLogicalVolume()); + } + for(auto imp : userImplants){ + currentImplant = imp; + imp->construct(); + imp->placeImplant(expHall->getLogicalVolume()); + } + + return expHall->getPhysicalVolume(); +} + +G4VPhysicalVolume* nDetConstruction::ConstructImplant(){ + if(!materials.materialsAreDefined()) + materials.initialize(); + + // Build experiment hall. + expHall->buildExpHall(&materials); + + // Place all detectors. + for(auto imp : userImplants){ + currentImplant = imp; + + // Build the detector + imp->construct(); // Place the detector into the world. + imp->placeImplant(expHall->getLogicalVolume()); + } + for(auto det : userDetectors){ + currentDetector = det; + // Build the detector + det->construct(); + // Place all detectors. det->placeDetector(expHall->getLogicalVolume()); } @@ -103,6 +136,36 @@ void nDetConstruction::ClearGeometry(){ for(auto det : userDetectors) delete det; userDetectors.clear(); + for(auto imp : userImplants) + delete imp; + userImplants.clear(); + + // Reset the scintillator copy number. + params.SetScintillatorCopyNumber(1); +} + +void nDetConstruction::ClearImplantGeometry(){ + // Clean-up previous geometry + G4GeometryManager::GetInstance()->OpenGeometry(); + G4PhysicalVolumeStore::GetInstance()->Clean(); + G4LogicalVolumeStore::GetInstance()->Clean(); + G4SolidStore::GetInstance()->Clean(); + G4LogicalSkinSurface::CleanSurfaceTable(); + G4LogicalBorderSurface::CleanSurfaceTable(); + G4SolidStore::GetInstance()->Clean(); + G4LogicalVolumeStore::GetInstance()->Clean(); + G4PhysicalVolumeStore::GetInstance()->Clean(); + + // Reset the world volume. Why is this needed? CRT + expHall->reset(); + + // Clear previous construction. + for(auto det : userDetectors) + delete det; + userDetectors.clear(); + for(auto imp : userImplants) + delete imp; + userImplants.clear(); // Reset the scintillator copy number. params.SetScintillatorCopyNumber(1); @@ -111,12 +174,15 @@ void nDetConstruction::ClearGeometry(){ void nDetConstruction::UpdateGeometry(){ // Define new one G4RunManager::GetRunManager()->DefineWorldVolume(ConstructDetector()); + G4RunManager::GetRunManager()->DefineWorldVolume(ConstructImplant()); G4RunManager::GetRunManager()->GeometryHasBeenModified(); G4RunManager::GetRunManager()->ReinitializeGeometry(); // Update the particle source if(currentDetector) nDetParticleSource::getInstance().SetDetector(currentDetector); + else if(currentImplant) + nDetParticleSource::getInstance().SetImplant(currentImplant); // Update the detector lists of all user run actions nDetThreadContainer *container = &nDetThreadContainer::getInstance(); @@ -183,6 +249,67 @@ bool nDetConstruction::AddGeometry(const G4String &geom){ // Set true isotropic source mode for multiple detectors if(userDetectors.size() > 1) nDetParticleSource::getInstance().SetRealIsotropicMode(true); + + // Set true isotropic source mode for multiple detectors + if(userImplants.size() > 1) + nDetParticleSource::getInstance().SetRealIsotropicMode(true); + + return true; +} + +bool nDetConstruction::AddImplantGeometry(const G4String &geom){ + // Define a new detector of the specified type + nDetImplant *newImplant = nDetDetectorTypes::getImplantType(geom, this, &materials); + + if(!newImplant){ // Invalid detector type + std::cout << Display::ErrorStr("nDetConstruction") << "User specified un-recognized detector type (" << geom << ")!" << Display::ResetStr() << std::endl; + return false; + } + + // Set the current detector to the new one + currentImplant = newImplant; + + // Segment the PMT photo-sensitive surface + if(params.PmtIsSegmented()){ + setSegmentedPmt(); + if(!gainMatrixFilename.empty()){ + loadPmtGainMatrix(); + } + } + + // Load the anode quantum efficiency + if(!spectralResponseFilename.empty()){ + loadPmtSpectralResponse(); + } + + // Copy the center-of-mass calculators to the new detector + centerOfMass *cmI = currentImplant->getCenterOfMass(); + currentImplant->copyCenterOfMass(center[0]); + + // Segment the PMT anodes + if(params.PmtIsSegmented()){ + cmI->setSegmentedPmt(¶ms); + + // Copy the PMT anode gain matrix + cmI->copyGainMatrix(¢er[0]); + } + + // Copy the PMT anode quantum efficiency curve + if(center[0].getPmtResponse()->getSpectralResponseEnabled()) + cmI->copySpectralResponse(¢er[0]); + + // Add the new detector assembly to the vector of detectors + userImplants.push_back(currentImplant); + + // Enable/disable overlap checking + currentImplant->setCheckOverlaps(fCheckOverlaps); + + // Update the detector's copy numbers. + currentImplant->setParentCopyNumber(userImplants.size()-1); + + // Set true isotropic source mode for multiple detectors + if(userImplants.size() > 1) + nDetParticleSource::getInstance().SetRealIsotropicMode(true); return true; } @@ -204,7 +331,7 @@ bool nDetConstruction::loadPmtSpectralResponse(){ } bool nDetConstruction::loadPmtGainMatrix(){ - if(!(center[0].loadGainMatrix(gainMatrixFilename.c_str()) && center[1].loadGainMatrix(gainMatrixFilename.c_str()))){ + if(!(center[1].loadGainMatrix(gainMatrixFilename.c_str()) && center[0].loadGainMatrix(gainMatrixFilename.c_str()))){ Display::ErrorPrint("Failed to load PMT anode gain matrix from file!", "nDetConstruction"); return false; } @@ -216,6 +343,8 @@ bool nDetConstruction::loadPmtGainMatrix(){ void nDetConstruction::AddLightGuideGDML(const G4String &input){ if(currentDetector) currentDetector->addLightGuideGDML(input); + else if(currentImplant) + currentImplant->addLightGuideGDML(input); else Display::ErrorPrint("Cannot add GDML light-guide before a detector is defined!", "nDetConstruction"); } @@ -223,6 +352,8 @@ void nDetConstruction::AddLightGuideGDML(const G4String &input){ void nDetConstruction::AddGrease(const G4String &input){ if(currentDetector) currentDetector->addGreaseLayer(input); + else if(currentImplant) + currentImplant->addGreaseLayer(input); else Display::ErrorPrint("Cannot add grease layer before a detector is defined!", "nDetConstruction"); } @@ -230,6 +361,8 @@ void nDetConstruction::AddGrease(const G4String &input){ void nDetConstruction::AddDiffuser(const G4String &input){ if(currentDetector) currentDetector->addDiffuserLayer(input); + else if(currentImplant) + currentImplant->addDiffuserLayer(input); else Display::ErrorPrint("Cannot add diffuser layer before a detector is defined!", "nDetConstruction"); } @@ -237,10 +370,19 @@ void nDetConstruction::AddDiffuser(const G4String &input){ void nDetConstruction::AddLightGuide(const G4String &input){ if(currentDetector) currentDetector->addLightGuideLayer(input); + else if(currentImplant) + currentImplant->addLightGuideLayer(input); else Display::ErrorPrint("Cannot add light-guide before a detector is defined!", "nDetConstruction"); } +void nDetConstruction::AddSegmentedLightGuide(const G4String &input){ + if(currentImplant) + currentImplant->addSegmentedLightGuideLayer(input); + else + Display::ErrorPrint("Cannot add segmented light-guide before a detector is defined!", "nDetConstruction"); +} + void nDetConstruction::AddDetectorArray(const G4String &input){ // Expects a space-delimited string of the form: // "addDiffuserLayer width(mm) height(mm) thickness(mm) material" @@ -251,7 +393,7 @@ void nDetConstruction::AddDetectorArray(const G4String &input){ std::cout << " nDetConstruction: SYNTAX: addArray \n"; return; } - double r0 = strtod(args.at(1).c_str(), NULL); + double r0 = strtod(args.at(1).c_str(), NULL)*cm; double startTheta = strtod(args.at(2).c_str(), NULL); double stopTheta = strtod(args.at(3).c_str(), NULL); int Ndet = strtol(args.at(4).c_str(), NULL, 10); @@ -267,6 +409,56 @@ void nDetConstruction::AddDetectorArray(const G4String &input){ } } +void nDetConstruction::AddImplantArray(const G4String &input){ + // Expects a space-delimited string of the form: + // "addDiffuserLayer width(mm) height(mm) thickness(mm) material" + std::vector args; + unsigned int Nargs = split_str(input, args); + if(Nargs < 3){ + std::cout << " nDetConstruction: Invalid number of arguments given to ::AddDetectorArray(). Expected 5, received " << Nargs << ".\n"; + std::cout << " nDetConstruction: SYNTAX: addArray \n"; + return; + } + double r0 = strtod(args.at(1).c_str(), NULL); + double startTheta = strtod(args.at(2).c_str(), NULL); + double stopTheta = strtod(args.at(3).c_str(), NULL); + int Ndet = strtol(args.at(4).c_str(), NULL, 10); + + if(args.at(0)=="hagrid"){ + // in this case r0 will be used as the half-width of a square around the point + if(Ndet!=8 && Ndet!=16){ + std::cout<<"!!!!!! ----- !!!!!! \n !!!!!! For preliminary testing please use Ndet=8 or 16 !!!!! \n !!!!!! ----- !!!!!!"< 1) + dTheta = (stopTheta-startTheta)/(Ndet-1); + for(int i = 0; i < Ndet; i++){ + //std::cout << " nDetConstruction: Adding detector (type=" << args.at(0) << ", r=" << r0 << ", theta=" << startTheta+dTheta*i << ")\n"; + params.SetPositionCylindrical(G4ThreeVector(r0, startTheta+dTheta*i, 0)); + params.SetRotation(G4ThreeVector(90, 0, startTheta+dTheta*i)); + AddImplantGeometry(args.at(0)); + } + } +} + void nDetConstruction::BuildExp(std::string expName_){ expHall->SetExp(expName_); } @@ -289,3 +481,8 @@ void nDetConstruction::GetCopiesOfDetectors(std::vector &detectors for(auto det : userDetectors) detectors.push_back(det->clone()); } + +void nDetConstruction::GetCopiesOfImplants(std::vector &implants) const { + for(auto imp : userImplants) + implants.push_back(imp->clone()); +} diff --git a/source/nDetConstructionMessenger.cc b/source/nDetConstructionMessenger.cc index d7aeec9..19acaea 100644 --- a/source/nDetConstructionMessenger.cc +++ b/source/nDetConstructionMessenger.cc @@ -11,8 +11,10 @@ #include "G4UIcmdWith3Vector.hh" #include "G4UIcmdWith3VectorAndUnit.hh" #include "G4UIcmdWithADouble.hh" +#include "G4UIcmdWithABool.hh" #include "G4UIcmdWithAnInteger.hh" #include "G4UIcmdWithoutParameter.hh" +#include "G4UIcmdWithABool.hh" #include "G4SystemOfUnits.hh" void nDetConstructionMessenger::addAllCommands(){ @@ -114,6 +116,53 @@ void nDetConstructionMessenger::addAllCommands(){ addCommand(new G4UIcmdWithoutParameter("/nDet/output/trace/params", this)); addGuidance("Print pulse and digitizer settings"); + + /////////////////////////////////////////////////////////////////////////////// + // Implant commands + /////////////////////////////////////////////////////////////////////////////// + + addDirectory("/nDet/implant/", "Implant geometry control"); + + addCommand(new G4UIcmdWithAString("/nDet/implant/addGeometry", this)); + addGuidance("Defines the Geometry of the implant"); + + addCommand(new G4UIcommand("/nDet/implant/update", this)); + addGuidance("Updates the implant Geometry"); + + addCommand(new G4UIcmdWithAString("/nDet/implant/setSpectralResponse", this)); + addGuidance("Load PMT spectral response from a root file"); + addGuidance("Input file MUST contain a TGraph named \"spec\""); + + addCommand(new G4UIcmdWithAString("/nDet/implant/setGainMatrix", this)); + addGuidance("Load segmented PMT anode gain matrix file"); + + addCommand(new G4UIcmdWithAString("/nDet/implant/addGreaseLayer", this)); + addGuidance("Add a layer of optical grease (all units in mm). SYNTAX: addGreaseLayer [thickness]"); + + addCommand(new G4UIcmdWithAString("/nDet/implant/addDiffuserLayer", this)); + addGuidance("Add a straight diffuser to the assembly (all units in mm). SYNTAX: addDiffuserLayer [material=G4_SILICON_DIOXIDE]"); + + addCommand(new G4UIcmdWithAString("/nDet/implant/addLightGuide", this)); + addGuidance("Add a trapezoidal light-guide to the assembly (all units in mm). SYNTAX: addLightGuide [material=G4_SILICON_DIOXIDE]"); + + addCommand(new G4UIcmdWithAString("/nDet/implant/loadLightGuide", this)); + addGuidance("Load a light-guide from a GDML geometry file. SYNTAX: loadLightGuide "); + + addCommand(new G4UIcmdWithoutParameter("/nDet/implant/clear", this)); + addGuidance("Clear all implant Geometry"); + + addCommand(new G4UIcmdWithAString("/nDet/implant/addArray", this)); + addGuidance("Add an array of multiple implants. SYNTAX: addArray "); + + addCommand(new G4UIcmdWithoutParameter("/nDet/implant/printAll", this)); + addGuidance("Print construction parameters for all defined implants"); + + addCommand(new G4UIcmdWithAString("/nDet/implant/setSegmentedLightGuide", this)); + addGuidance("Sets whether to use a segmented light guide. Must be true for any segmentation to be implemented.\n SYNTAX: <# x seg> <# y seg> "); + + // addCommand(new G4UIcmdWithABool("/nDet/implant/setReconLogic",this)); + // addGuidance("Sets the logic used for calculating the reconstructed position, 0 = anger logic, 1 = sipm logic"); + } void nDetConstructionMessenger::SetNewChildValue(G4UIcommand* command, G4String newValue){ @@ -247,5 +296,50 @@ void nDetConstructionMessenger::SetNewChildValue(G4UIcommand* command, G4String else if(index == 16){ prL->print(); // Only show the left side, because they're both the same } + + //Implant commands + else if(index == 17){ + fDetector->AddImplantGeometry(newValue); + } + else if(index == 18){ + fDetector->UpdateGeometry(); + } + else if(index == 19){ + fDetector->setPmtSpectralResponse(newValue.c_str()); + } + else if(index == 20){ + fDetector->setPmtGainMatrix(newValue.c_str()); + } + else if(index == 21){ + fDetector->AddGrease(newValue); + } + else if(index == 22){ + fDetector->AddDiffuser(newValue); + } + else if(index == 23){ + fDetector->AddLightGuide(newValue); + } + else if(index == 24){ + fDetector->AddLightGuideGDML(newValue); + } + else if(index == 25){ + fDetector->ClearGeometry(); + } + else if(index == 26){ + fDetector->AddImplantArray(newValue); + } + else if(index == 27){ + fDetector->PrintAllDetectors(); + } + + //LightGuideParameterisation commands + else if(index == 28){ + fDetector->AddSegmentedLightGuide(newValue); + } + else if(index == 29){ + bool val = command->ConvertToBool(newValue); + std::cout<<"Setting Construction Recon Logic to "<setReconLogic(val); + } } } diff --git a/source/nDetDataPack.cc b/source/nDetDataPack.cc index 6fab091..2d4143c 100644 --- a/source/nDetDataPack.cc +++ b/source/nDetDataPack.cc @@ -4,17 +4,19 @@ #include "nDetDataPack.hh" -void nDetDataPack::setDataAddresses(nDetEventStructure *evt, nDetOutputStructure *out, nDetMultiOutputStructure *mult, nDetDebugStructure *debug, nDetTraceStructure *trace){ +void nDetDataPack::setDataAddresses(nDetEventStructure *evt, nDetOutputStructure *out, nDetImplantOutputStructure *outImp, nDetMultiOutputStructure *mult, nDetDebugStructure *debug, nDetTraceStructure *trace){ evtData = evt; outData = out; + outImplantData = outImp; multData = mult; debugData = debug; traceData = trace; } -void nDetDataPack::copyData(nDetEventStructure *evt, nDetOutputStructure *out, nDetMultiOutputStructure *mult, nDetDebugStructure *debug, nDetTraceStructure *trace) const { +void nDetDataPack::copyData(nDetEventStructure *evt, nDetOutputStructure *out, nDetImplantOutputStructure *outImp, nDetMultiOutputStructure *mult, nDetDebugStructure *debug, nDetTraceStructure *trace) const { (*evt) = (*evtData); (*out) = (*outData); + (*outImp) = (*outImplantData); (*mult) = (*multData); (*debug) = (*debugData); (*trace) = (*traceData); @@ -31,6 +33,7 @@ int nDetDataPack::getEventID() const { void nDetDataPack::clear(){ evtData->Zero(); outData->Zero(); + outImplantData->Zero(); multData->Zero(); debugData->Zero(); traceData->Zero(); diff --git a/source/nDetDetector.cc b/source/nDetDetector.cc index 9ec014b..3b158d4 100644 --- a/source/nDetDetector.cc +++ b/source/nDetDetector.cc @@ -13,6 +13,7 @@ #include "G4Trd.hh" #include "G4Cons.hh" #include "G4Sphere.hh" +#include "G4Trap.hh" #include "nDetDetector.hh" #include "nDetDetectorLayer.hh" @@ -160,10 +161,10 @@ void nDetDetectorParams::UpdateSize(){ /////////////////////////////////////////////////////////////////////////////// nDetDetector::nDetDetector(nDetConstruction *detector, nDetMaterials *matptr) : nDetDetectorParams(detector->GetDetectorParameters()), - assembly_logV(NULL), assembly_physV(NULL), - layerSizeX(0), layerSizeY(0), offsetZ(0), - parentCopyNum(0), firstSegmentCopyNum(0), lastSegmentCopyNum(0), - checkOverlaps(false) + assembly_logV(NULL), assembly_physV(NULL), + layerSizeX(0), layerSizeY(0), offsetZ(0), + parentCopyNum(0), firstSegmentCopyNum(0), lastSegmentCopyNum(0), + checkOverlaps(false) { copyCenterOfMass(*detector->GetCenterOfMassL(), *detector->GetCenterOfMassR()); materials = matptr; @@ -270,6 +271,7 @@ void nDetDetector::construct(){ scintMaterial = materials->getUserDetectorMaterial(detectorMaterialName); scintVisAtt = materials->getUserVisAttributes(detectorMaterialName); wrappingMaterial = materials->getUserSurfaceMaterial(wrappingMaterialName); + outerMylar = materials->fMylar; wrappingVisAtt = materials->getUserVisAttributes(wrappingMaterialName); wrappingOpSurf = materials->getUserOpticalSurface(wrappingMaterialName); @@ -576,3 +578,502 @@ void nDetDetector::loadLightGuide(gdmlSolid *solid, const G4ThreeVector &rotatio offsetZ += solid->getLength(); fTrapezoidLength = solid->getLength()*mm; } + +/////////////////////////////////////////////////////////////////////////////// +// class nDetImplant +/////////////////////////////////////////////////////////////////////////////// + +nDetImplant::nDetImplant(nDetConstruction *detector, nDetMaterials *matptr) : nDetDetectorParams(detector->GetDetectorParameters()), + assembly_logV(NULL), assembly_physV(NULL), + layerSizeX(0), layerSizeY(0), offsetZ(0), + parentCopyNum(0), firstSegmentCopyNum(0), lastSegmentCopyNum(0), + checkOverlaps(true) +{ + copyCenterOfMass(*detector->GetCenterOfMass()); //This has been adjusted + materials = matptr; + sipmLogic = detector->GetDetectorParameters().GetReconLogic(); +} + +nDetImplant::~nDetImplant(){ + /*for(std::vector::iterator iter = userLayers.begin(); iter != userLayers.end(); iter++){ + delete (*iter); // This causes a seg-fault + } + userLayers.clear();*/ +} + +nDetImplant nDetImplant::clone() const { + // Clone this detector's parameters + nDetImplant retval(*this); + + // Copy the center of mass calculators explicitly + retval.cmI = cmI.clone(); + + return retval; +} + +void nDetImplant::getCurrentOffset(G4double &x_, G4double &y_, G4double &z_){ + x_ = layerSizeX; + y_ = layerSizeY; + z_ = offsetZ; +} + +void nDetImplant::setPositionAndRotation(const G4ThreeVector &pos, const G4RotationMatrix &rot){ + detectorPosition = pos; + detectorRotation = rot; +} + +void nDetImplant::setCurrentOffset(const G4double &x_, const G4double &y_, const G4double &z_){ + layerSizeX = x_; + layerSizeY = y_; + offsetZ = z_; +} + +void nDetImplant::buildAllLayers(){ + for(std::vector::iterator iter = userLayers.begin(); iter != userLayers.end(); iter++){ + (*iter)->construct(this); + } +} + +void nDetImplant::placeImplant(G4LogicalVolume *parent){ + assembly_physV = new G4PVPlacement(&detectorRotation, detectorPosition, assembly_logV, "Assembly", parent, 0, 0, false); + assembly_physV->SetCopyNo(parentCopyNum); + + // Do some post-placement processing + afterPlacement(); +} + +void nDetImplant::clear(){ + cmI.clear(); +} + +void nDetImplant::copyCenterOfMass(const centerOfMass &implant){ + cmI = implant.clone(); +} + +bool nDetImplant::checkPmtCopyNumber(const G4int &num, bool &isImp) const { + isImp = 1; + return (num == 2*parentCopyNum); +} + +bool nDetImplant::getSegmentFromCopyNum(const G4int ©Num, G4int &col, G4int &row) const { + if(!this->checkCopyNumber(copyNum)) return false; + col = (copyNum-firstSegmentCopyNum) / fNumRows; + row = (copyNum-firstSegmentCopyNum) % fNumRows; + return true; +} + +void nDetImplant::addLightGuideGDML(const G4String &input){ + addLayer(new gdmlLightGuideLayer(input)); +} + +void nDetImplant::addGreaseLayer(const G4String &input){ + addLayer(new greaseLayer(input)); +} + +void nDetImplant::addDiffuserLayer(const G4String &input){ + addLayer(new diffuserLayer(input)); +} + +void nDetImplant::addLightGuideLayer(const G4String &input){ + addLayer(new lightGuideLayer(input)); +} + +void nDetImplant::addSegmentedLightGuideLayer(const G4String &input){ + addLayer(new segLightGuideLayer(input)); +} + +void nDetImplant::construct(){ + // Update the size of the assembly in the event it has changed + UpdateSize(); + + // Prepare to build the detector and compute the maximum size of the detector volume + prepareToBuild(); + + // Build the assembly volume + constructAssembly(); + + // Get materials and visual attributes + scintMaterial = materials->getUserDetectorMaterial(detectorMaterialName); + scintVisAtt = materials->getUserVisAttributes(detectorMaterialName); + wrappingMaterial = materials->getUserSurfaceMaterial(wrappingMaterialName); + outerMylar = materials->fMylar; + wrappingVisAtt = materials->getUserVisAttributes(wrappingMaterialName); + windowVisAtt = materials->visWindow; + wrappingOpSurf = materials->getUserOpticalSurface(wrappingMaterialName); + wrappingOuterOpSurf = materials->fMylarOpSurf; + + // Build the geometry + buildDetector(); + + // Generate all user-defined layers. + buildAllLayers(); + + // Attach PMT + constructPSPmt(); +} + +G4LogicalVolume *nDetImplant::constructAssembly(){ + // Calculate the dimensions of the detector + G4double assemblyWidth = maxBodySize.getX() + 2*fWrappingThickness; + G4double assemblyHeight = maxBodySize.getY() + 2*fWrappingThickness; + G4double assemblyLength = maxBodySize.getZ(); + // Account for the size of the PSPMT + assemblyWidth = std::max(assemblyWidth, pmtWidth); + assemblyHeight = std::max(assemblyHeight, pmtHeight); + assemblyLength += (2*fGreaseThickness+fWindowThickness+fSensitiveThickness+fWrappingThickness*3/2); + std::cout<<"assemblyLength:: "<0.1*cm) ? 0 : assemblyLength+2*dzThick; + // assemblyLength += 2*(2*fGreaseThickness+fWindowThickness+fSensitiveThickness+dzThick); + + // Account for the additional component layers + for(std::vector::iterator iter = userLayers.begin(); iter != userLayers.end(); iter++){ + if(!(*iter)->decodeString()){ + std::cout << " nDetImplant: Invalid number of arguments given to ::decodeString(). Expected " << (*iter)->getNumRequiredArgs() << " but received " << (*iter)->getNumSuppliedArgs() << ".\n"; + std::cout << " nDetImplant: SYNTAX: " << (*iter)->syntaxStr() << std::endl; + continue; + } + assemblyWidth = std::max(assemblyWidth, (*iter)->getSizeX()); + assemblyHeight = std::max(assemblyHeight, (*iter)->getSizeY()); + assemblyLength += (*iter)->getSizeZ(); + } + + // Build the assembly box + G4Box *assembly = new G4Box("assembly", assemblyWidth/2, assemblyHeight/2, assemblyLength/2); + assembly_logV = new G4LogicalVolume(assembly, materials->fAir, "assembly_logV"); + assembly_logV->SetVisAttributes(materials->visAssembly); + + return assembly_logV; +} + +G4PVPlacement *nDetImplant::addToDetectorBody(G4LogicalVolume *volume, const G4String &name/*=""*/, const G4ThreeVector &pos/*=G4ThreeVector(0,0,0)*/, G4RotationMatrix *rot/*=NULL*/){ + return (new G4PVPlacement(rot, pos, volume, (name.empty() ? volume->GetName() : name), assembly_logV, false, 0, checkOverlaps)); +} + +G4PVPlacement *nDetImplant::addSegmentToBody(G4LogicalVolume *volume, const G4String &name/*=""*/, const G4ThreeVector &pos/*=G4ThreeVector(0,0,0)*/, G4RotationMatrix *rot/*=NULL*/){ + return (new G4PVPlacement(rot, pos, volume, (name.empty() ? volume->GetName() : name), assembly_logV, false, lastSegmentCopyNum++, checkOverlaps)); +} + +G4PVPlacement *nDetImplant::addBackComponent(G4LogicalVolume *volume, const G4double &offset, const G4String &name/*=""*/, G4RotationMatrix *rot/*=NULL*/){ + return (new G4PVPlacement(rot, G4ThreeVector(0, 0, offset), volume, (name.empty() ? volume->GetName() : name), assembly_logV, false, 2*parentCopyNum, checkOverlaps)); +} + +void nDetImplant::addBackComponent(G4PVPlacement* &phys1, G4LogicalVolume *volume, const G4double &offset, const G4String &name/*=""*/, G4RotationMatrix *rot/*=NULL*/){ + phys1 = (new G4PVPlacement(rot, G4ThreeVector(0, 0, offset), volume, (name.empty() ? volume->GetName() : name), assembly_logV, false, 2*parentCopyNum, checkOverlaps)); +} + +G4PVPlacement *nDetImplant::addFrontComponent(G4LogicalVolume *volume, const G4double &offset, const G4String &name/*=""*/, G4RotationMatrix *rot/*=NULL*/){ + return (new G4PVPlacement(rot, G4ThreeVector(0, 0, offset), volume, (name.empty() ? volume->GetName() : name), assembly_logV, false, 2*parentCopyNum, checkOverlaps)); +} + +void nDetImplant::addFrontComponent(G4PVPlacement* &phys1, G4LogicalVolume *volume, const G4double &offset, const G4String &name/*=""*/, G4RotationMatrix *rot/*=NULL*/){ + phys1 = (new G4PVPlacement(rot, G4ThreeVector(0, 0, offset), volume, (name.empty() ? volume->GetName() : name), assembly_logV, false, 2*parentCopyNum, checkOverlaps)); +} + +void nDetImplant::prepareToBuild(){ + maxBodySize = G4ThreeVector(fDetectorWidth, fDetectorHeight, fDetectorLength); +} + +void nDetImplant::constructPSPmt(){ + // Build the sensitive PMT surface. + const G4String name = "psSiPM"; + + G4double sensitiveZ = offsetZ + fGreaseThickness + fWindowThickness + fSensitiveThickness/2; + G4double wrappingThickness = fGreaseThickness + fWindowThickness; + + // The optical grease layer. + G4PVPlacement *greasePhys = NULL; + if(fGreaseThickness > 0){ + G4double greaseZ = offsetZ + fGreaseThickness/2; + + G4CSGSolid *grease_solidV = getVolume("window_solidV", pmtWidth, pmtHeight, fGreaseThickness); + G4LogicalVolume *grease_logV = new G4LogicalVolume(grease_solidV, materials->fGrease, "grease_logV"); + + grease_logV->SetVisAttributes(materials->visGrease); + + greasePhys = addBackComponent(grease_logV, greaseZ, "Grease1"); + + if(!fPolishedInterface){ + for(std::vector::iterator iter = scintBody_physV.begin(); iter != scintBody_physV.end(); iter++){ + new G4LogicalBorderSurface("GreaseInterface", (*iter), greasePhys, materials->fGreaseOpSurf); + } + } + + // Clear all scintillator placements. + scintBody_physV.clear(); + } + + G4PVPlacement *windowPhys = NULL; + if(fWindowThickness > 0){ // The quartz window + G4double windowZ = offsetZ + fGreaseThickness + fWindowThickness/2; + + G4CSGSolid *window_solidV = getVolume("window_solidV", pmtWidth, pmtHeight, fWindowThickness); + G4LogicalVolume *window_logV = new G4LogicalVolume(window_solidV, materials->fSiO2, "window_logV"); + + window_logV->SetVisAttributes(materials->visWindow); + + windowPhys = addBackComponent(window_logV, windowZ, "Quartz"); + } + + // Build the wrapping. + if(WrappingEnabled() && wrappingThickness > 0){ + G4CSGSolid *boundingBox = getVolume("", pmtWidth, pmtHeight, wrappingThickness); + G4CSGSolid *wrappingBox = getVolume("", pmtWidth + 2*fWrappingThickness, pmtHeight + 2*fWrappingThickness, wrappingThickness); + + G4SubtractionSolid *greaseWrapping = new G4SubtractionSolid("", wrappingBox, boundingBox); + G4LogicalVolume *greaseWrapping_logV = new G4LogicalVolume(greaseWrapping, wrappingMaterial, "greaseWrapping_logV"); + greaseWrapping_logV->SetVisAttributes(wrappingVisAtt); + + G4double wrappingZ = offsetZ + fGreaseThickness/2 + fWindowThickness/2; + + // Place the wrapping around the scintillator. + G4PVPlacement *greaseWrapping_physV; + + if(greasePhys){ + new G4LogicalBorderSurface("Wrapping", greasePhys, greaseWrapping_physV, wrappingOpSurf); + } + if(windowPhys){ + new G4LogicalBorderSurface("Wrapping", windowPhys, greaseWrapping_physV, wrappingOpSurf); + } + } + + // The photon sensitive surface + G4CSGSolid *sensitive_solidV = getVolume(name+"_solidV", pmtWidth, pmtHeight, fSensitiveThickness); + G4LogicalVolume *sensitive_logV = new G4LogicalVolume(sensitive_solidV, materials->fSilicon, name+"_logV"); + sensitive_logV->SetVisAttributes(materials->visSensitive); + + // Logical skin surface. + new G4LogicalSkinSurface(name, sensitive_logV, materials->fSiliconOpSurf); + + //addMirroredComponents(sensitive_logV, sensitiveZ, name); + addBackComponent(sensitive_logV, sensitiveZ, name); + + // Move the current offset past the PMT + layerSizeX = pmtWidth; + layerSizeY = pmtHeight; + offsetZ += fGreaseThickness + fWindowThickness + fSensitiveThickness; +} + +G4CSGSolid *nDetImplant::getVolume(const G4String &name, const G4double &width, const G4double &height, const G4double &length){ + G4CSGSolid *retval; + if(fSquarePMTs) + retval = new G4Box(name, width/2, height/2, length/2); + else + retval = new G4Tubs(name, 0, width/2, length/2, 0, 2*CLHEP::pi); + return retval; +} + +G4CSGSolid *nDetImplant::getLightGuideVolume(const G4String &name, const G4double &w1, const double &w2, const double &h1, const double &h2, const G4double &length){ + G4CSGSolid *retval; + if(fSquarePMTs) + retval = new G4Trd(name, w1/2, w2/2, h1/2, h2/2, length/2); + else + retval = new G4Cons(name, 0, w1/2, 0, w2/2, length/2, 0, 2*CLHEP::pi); + return retval; +} + +void nDetImplant::applyGreaseLayer(){ + std::cout<<"Layer size x "<applyGreaseLayer(layerSizeX, layerSizeY); +} + +void nDetImplant::applyGreaseLayer(const G4double &x, const G4double &y, double thickness/*=0*/){ + if(thickness <= 0) + thickness = fGreaseThickness; + if(thickness > 0){ + G4CSGSolid *grease_solidV = getVolume("grease", x, y, thickness); + G4LogicalVolume *grease_logV = new G4LogicalVolume(grease_solidV, materials->fGrease, "grease_logV"); + grease_logV->SetVisAttributes(materials->visGrease); + + // Add the optical grease to the assembly + //addMirroredComponents(grease_logV, offsetZ+thickness/2, "Grease"); + G4PVPlacement *greaseLogical = addBackComponent(grease_logV, offsetZ+thickness/2, "Grease0"); + + // Offset the other layers to account for the layer of optical grease + layerSizeX = x; + layerSizeY = y; + offsetZ += thickness; + } +} + +void nDetImplant::applyDiffuserLayer(){ + this->applyDiffuserLayer(layerSizeX, layerSizeY, fDiffuserLength); +} + +void nDetImplant::applyDiffuserLayer(const G4double &x, const G4double &y, const double &thickness){ + if(thickness > 0){ // Build the light diffusers (if needed) + G4CSGSolid *lightDiffuser = getVolume("lightDiffuser", x, y, thickness); + G4LogicalVolume *lightDiffuserLog = new G4LogicalVolume(lightDiffuser, materials->fSiO2, "lightDiffuser_logV"); + + // Add the optical grease to the assembly + //addMirroredComponents(lightDiffuserLog, offsetZ+thickness/2, "Diffuser"); + G4PVPlacement *lightDiffuserLogical = addBackComponent(lightDiffuserLog, offsetZ+thickness/2, "Diffuser"); + + // Offset the other layers to account for the light-diffuser + layerSizeX = x; + layerSizeY = y; + offsetZ += thickness; + } +} + +void nDetImplant::applyLightGuide(){ + this->applyLightGuide(layerSizeX, pmtWidth, layerSizeY, pmtHeight, fTrapezoidLength); +} + +void nDetImplant::applyLightGuide(const G4double &x2, const G4double &y2){ + this->applyLightGuide(layerSizeX, x2, layerSizeY, y2, fTrapezoidLength); +} + +void nDetImplant::applyLightGuide(const G4double &x1, const G4double &x2, const G4double &y1, const G4double &y2, const double &thickness){ + if(thickness > 0){ // Build the light guides (if needed) + const G4double trapAngleXZ = std::atan2(2*thickness, x1-x2); + const G4double trapAngleYZ = std::atan2(2*thickness, y1-y2); + + const G4double deltaX = fWrappingThickness/std::sin(trapAngleXZ); + const G4double deltaY = fWrappingThickness/std::sin(trapAngleYZ); + + G4double trapezoidZ = offsetZ + thickness/2; + + std::string trapName = "Acrylic"; + + // Build the light-guide. + G4CSGSolid *lightGuide = getLightGuideVolume("lightGuide", x1, x2, y1, y2, thickness); + G4LogicalVolume *lightGuideLog = new G4LogicalVolume(lightGuide, materials->fSiO2, "lightGuide_logV"); + + G4RotationMatrix *rightRotation = new G4RotationMatrix(); + rightRotation->rotateX(CLHEP::pi); + + // Place the light guides. + G4PVPlacement *trapPhysical = addBackComponent(lightGuideLog, trapezoidZ, trapName); + + // Build the wrapping. + if(WrappingEnabled()){ + G4CSGSolid *wrappingSolid = getLightGuideVolume("wrapping", x1+2*deltaX, x2+2*deltaY, y1+2*deltaX, y2+2*deltaY, thickness); + G4SubtractionSolid *wrapping = new G4SubtractionSolid("wrapping", wrappingSolid, lightGuide); + G4LogicalVolume *wrapping_logV = new G4LogicalVolume(wrapping, wrappingMaterial, "wrapping_logV"); + wrapping_logV->SetVisAttributes(wrappingVisAtt); + + // Place the wrapping around the light guides. + G4PVPlacement *trapWrapping = addBackComponent(wrapping_logV, trapezoidZ, trapName); + + // Reflective wrapping. + new G4LogicalBorderSurface("Wrapping", trapPhysical, trapWrapping, wrappingOpSurf); + } + + // Offset the other layers to account for the light-guide + layerSizeX = x2; + layerSizeY = y2; + offsetZ += thickness; + } +} + +void nDetImplant::applySegmentedLightGuide(G4int Xseg, G4int Yseg, G4double spacing, G4double topWidth, G4double topThick, G4double botWidth, G4double botThick, G4double zThick){ + G4int numSegs = Xseg*Yseg; + std::string name = "segLightGuide"; + auto lg_mat = materials->fAcrylic; + auto seg_solid = new G4Trap("trap"); + //auto seg_solid = new G4Box("seg_solid",2*mm,2*mm,10*mm); + auto lg_box = new G4Box("lg_box",topWidth/2.,topThick/2.,zThick/2.); + //auto lg_box = new G4Box("lg_box",fDetectorWidth/2.,fDetectorHeight/2.,zThick/2.); + auto lg_log = new G4LogicalVolume(lg_box,materials->fAir,"lg_log"); + + //Attempt to create a solid for the wrapping + G4double cellXt = ( topWidth- fWrappingThickness*( Xseg-1))/ Xseg; + G4double cellXb = ( botWidth- fWrappingThickness*( Xseg-1))/ Xseg; + G4double cellYt = ( topThick- fWrappingThickness*( Yseg-1))/ Yseg; + G4double cellYb = ( botThick- fWrappingThickness*( Yseg-1))/ Yseg; + std::vector wrappings_vec; + for(int copyNo=0;copyNofMylar, "wrapping_logV"); + wrapping_logV->SetVisAttributes(wrappingVisAtt); + G4PVPlacement *wrap_place = new G4PVPlacement(nullptr,G4ThreeVector(xpos,ypos,0),wrapping_logV,"wrap_phys",lg_log,false,0,true); + new G4LogicalBorderSurface("Wrapping", seg_place, wrap_place, wrappingOuterOpSurf); + } + } + G4PVPlacement *lightGuideBox = addBackComponent(lg_log,offsetZ+zThick/2.,name); + offsetZ+=zThick; + return; +} + +void nDetImplant::loadGDML(gdmlSolid *solid){ + if(!solid || !solid->isLoaded()) + return; + + std::cout << " nDetImplant: Loaded GDML model (name=" << solid->getName() << ") with size x=" << solid->getWidth() << " mm, y=" << solid->getThickness() << " mm, z=" << solid->getLength() << " mm\n"; + + // Place loaded model into the assembly. + solid->placeSolid(assembly_logV, checkOverlaps); +} + +void nDetImplant::loadLightGuide(gdmlSolid *solid, const G4ThreeVector &rotation){ + if(!solid || !solid->isLoaded()) + return; + + // Set internal reflectors + solid->setLogicalBorders("InnerWrapping", materials->fEsrOpSurf); + + G4double trapezoidZ = offsetZ + solid->getLength()/2.0; + std::cout << " nDetConstruction: Loaded GDML model (name=" << solid->getName() << ") with size x=" << solid->getWidth() << " mm, y=" << solid->getThickness() << " mm, z=" << solid->getLength() << " mm\n"; + + // Place loaded model into the assembly. + // Place the light-guide on the positive z side. + solid->setPosition(G4ThreeVector(0, 0, trapezoidZ)); + solid->placeSolid(assembly_logV, checkOverlaps); + + // And on the negative z side. + G4RotationMatrix *trapRot = new G4RotationMatrix(); + trapRot->rotateX(rotation.getX()-CLHEP::pi); + solid->placeSolid(trapRot, G4ThreeVector(0, 0, -trapezoidZ), assembly_logV, checkOverlaps); + + layerSizeX = solid->getWidth(); + layerSizeY = solid->getThickness(); + offsetZ += solid->getLength(); + fTrapezoidLength = solid->getLength()*mm; +} + diff --git a/source/nDetDetectorLayer.cc b/source/nDetDetectorLayer.cc index ebac2d8..3d7fd40 100644 --- a/source/nDetDetectorLayer.cc +++ b/source/nDetDetectorLayer.cc @@ -4,6 +4,7 @@ #include "nDetDetectorLayer.hh" #include "optionHandler.hh" // split_str + /////////////////////////////////////////////////////////////////////////////// // class greaseLayer /////////////////////////////////////////////////////////////////////////////// @@ -23,6 +24,10 @@ void greaseLayer::construct(nDetDetector *obj){ obj->applyGreaseLayer(x, y, thickness); } +void greaseLayer::construct(nDetImplant *obj){ + obj->applyGreaseLayer(x, y, thickness); +} + std::string greaseLayer::syntaxStr() const { return std::string("addGreaseLayer [thickness]"); } @@ -49,6 +54,10 @@ void diffuserLayer::construct(nDetDetector *obj){ obj->applyDiffuserLayer(x, y, thickness); } +void diffuserLayer::construct(nDetImplant *obj){ + obj->applyDiffuserLayer(x, y, thickness); +} + std::string diffuserLayer::syntaxStr() const { return std::string("addDiffuserLayer [material=G4_SILICON_DIOXIDE]"); } @@ -77,10 +86,54 @@ void lightGuideLayer::construct(nDetDetector *obj){ obj->applyLightGuide(x1, x2, y1, y2, thickness); } +void lightGuideLayer::construct(nDetImplant *obj){ + obj->applyLightGuide(x1, x2, y1, y2, thickness); +} + std::string lightGuideLayer::syntaxStr() const { return std::string("addLightGuide [material=G4_SILICON_DIOXIDE]"); } +/////////////////////////////////////////////////////////////////////////////// +// class segLightGuideLayer +/////////////////////////////////////////////////////////////////////////////// + +segLightGuideLayer::segLightGuideLayer(const +G4String &arg_) : nDetWorldObject(arg_,8), fXseg(0),fYseg(0),fspacing(0.),ftopWidth(0.),ftopThick(0.),fbotWidth(0.),fbotThick(0.),fzThick(0.),fSegMaterial("G4_Pyrex_Glass"){ + material = "G4_Pyrex_Glass"; +} + +segLightGuideLayer::~segLightGuideLayer(){ + G4cout<<"Deleting segLightGuideLayer"<applyGreaseLayer(ftopWidth,ftopThick); + obj->applySegmentedLightGuide(fXseg, fYseg, fspacing, ftopWidth, ftopThick, fbotWidth, fbotThick, fzThick); + obj->setSegZThick(fzThick); +} + +std::string segLightGuideLayer::syntaxStr() const{ + return std::string("<# x seg> <# y seg> "); +} + + /////////////////////////////////////////////////////////////////////////////// // class gdmlLightGuideLayer /////////////////////////////////////////////////////////////////////////////// @@ -106,6 +159,10 @@ void gdmlLightGuideLayer::construct(nDetDetector *obj){ obj->loadLightGuide(&solid, rotVector); } +void gdmlLightGuideLayer::construct(nDetImplant *obj){ + obj->loadLightGuide(&solid, rotVector); +} + std::string gdmlLightGuideLayer::syntaxStr() const { return std::string("loadLightGuide "); } diff --git a/source/nDetDetectorMessenger.cc b/source/nDetDetectorMessenger.cc index ecf2772..bb2d934 100644 --- a/source/nDetDetectorMessenger.cc +++ b/source/nDetDetectorMessenger.cc @@ -7,6 +7,7 @@ #include "G4UIcmdWith3Vector.hh" #include "G4UIcmdWith3VectorAndUnit.hh" #include "G4UIcmdWithADouble.hh" +#include "G4UIcmdWithABool.hh" #include "G4UIcmdWithAnInteger.hh" #include "G4UIcmdWithoutParameter.hh" #include "G4SystemOfUnits.hh" @@ -97,6 +98,126 @@ void nDetDetectorMessenger::addAllCommands(){ addCommand(new G4UIcmdWithADouble("/nDet/detector/setDetectorHeight", this)); addGuidance("Defines the height (Y) of the detector in cm"); + + +/////////////////////////////////////////////////////////////////////////////// +// Implant commands +/////////////////////////////////////////////////////////////////////////////// + + addDirectory("/nDet/implant/", "Detector geometry control"); + + addCommand(new G4UIcmdWithAString("/nDet/implant/setPmtDimensions", this)); + addGuidance("Defines the size of the SiPMs in mm. SYNTAX: setPmtDimensions [sizeY]"); + + addCommand(new G4UIcmdWithADouble("/nDet/implant/setDetectorLength", this)); + addGuidance("Defines the length (Z) of the implant in cm"); + + addCommand(new G4UIcmdWithADouble("/nDet/implant/setDetectorWidth", this)); + addGuidance("Defines the width (X) of the implant in cm"); + + addCommand(new G4UIcmdWithADouble("/nDet/implant/setDetectorThickness", this)); + addGuidance("Defines the thickness of the plastic in mm"); + + addCommand(new G4UIcmdWithADouble("/nDet/implant/setMylarThickness", this)); + addGuidance("Defines the thickness of the plastic the mylar in mm (0 for no mylar)"); + + addCommand(new G4UIcmdWithADouble("/nDet/implant/setGreaseThickness", this)); + addGuidance("Defines the thickness of the optical grease layer in mm (0 for no grease)"); + + addCommand(new G4UIcmdWithADouble("/nDet/implant/setTrapezoidLength", this)); + addGuidance("Defines the length of the trapezoidal part of ellipse in cm"); + + addCommand(new G4UIcmdWithAnInteger("/nDet/implant/setNumColumns", this)); + addGuidance("Set the number of columns in a segmented scintillator."); + + addCommand(new G4UIcmdWithAnInteger("/nDet/implant/setNumRows", this)); + addGuidance("Set the number of rows in a segmented scintillator."); + + addCommand(new G4UIcmdWithAnInteger("/nDet/implant/setPmtColumns", this)); + addGuidance("Set the number of anode columns in a segmented PSPMT."); + + addCommand(new G4UIcmdWithAnInteger("/nDet/implant/setPmtRows", this)); + addGuidance("Set the number of anode rows in a segmented PSPMT."); + + addCommand(new G4UIcmdWithADouble("/nDet/implant/setDiffuserLength", this)); + addGuidance("Defines the length of the straight light diffuser in cm"); + + addCommand(new G4UIcmdWithAString("/nDet/implant/setWrapping", this)); + addGuidance("Set the material to use for reflective wrapping"); + + addCommand(new G4UIcmdWithAString("/nDet/implant/setMaterial", this)); + addGuidance("Set the material to use for implant construction."); + + addCommand(new G4UIcmdWith3VectorAndUnit("/nDet/implant/setPosition", this)); // position of source in cartesian coordinates (x, y, z). + addGuidance("Set the position of the implant in cartesian coordinates (x, y, z)"); + + addCommand(new G4UIcmdWith3Vector("/nDet/implant/setCylindrical", this)); // position of source in cylindrical coordinates (r, theta, y). + addGuidance("Set the position of the implant in cylindrical coordinates (r, theta, y) where r and y are in cm and theta is in degrees"); + + addCommand(new G4UIcmdWith3Vector("/nDet/implant/setSpherical", this)); // position of source in spherical coordinates (r, theta, phi). + addGuidance("Set the position of the implant in spherical coordinates (r, theta, phi) where r is in cm and theta and phi are in degrees"); + + addCommand(new G4UIcmdWith3Vector("/nDet/implant/setRotation", this)); // rotation of implant. + addGuidance("Set the rotation of the implant by specifying angles about the x, y, and z axes (in deg)"); + + addCommand(new G4UIcmdWithADouble("/nDet/implant/setWindowThickness", this)); + addGuidance("Defines the thickness of the pspmt quartz window in mm (0 for no window)"); + + addCommand(new G4UIcmdWithAString("/nDet/implant/setPolished", this)); + addGuidance("Enable or disable polished optical grease faces (disabled by default)"); + addCandidates("true false"); + + addCommand(new G4UIcmdWithoutParameter("/nDet/implant/setStart", this)); + addGuidance("Mark the current implant as a start implant"); + + addCommand(new G4UIcmdWithAString("/nDet/implant/setSquarePmt", this)); + addGuidance("Enable or disable square PMTs (enabled by default). If disabled, circular PMTs will be used"); + addCandidates("true false"); + + addCommand(new G4UIcmdWithADouble("/nDet/implant/setSegmentWidth", this)); + addGuidance("Set the width of scintillator segments for segmented implants (in mm)"); + + addCommand(new G4UIcmdWithADouble("/nDet/implant/setSegmentHeight", this)); + addGuidance("Set the height of scintillator segments for segmented implants (in mm)"); + + addCommand(new G4UIcmdWithADouble("/nDet/implant/setTrapezoidAngle", this)); + addGuidance("Defines the angle of the trapezoidal part of ellipse wrt the edge of the rectangular body (in degrees)"); + + addCommand(new G4UIcmdWithADouble("/nDet/implant/setDetectorHeight", this)); + addGuidance("Defines the height (Y) of the implant in cm"); + + addCommand(new G4UIcmdWithABool("/nDet/implant/setReconLogic",this)); + addGuidance("Sets the logic used for calculating the reconstructed position, 0 = anger logic, 1 = sipm logic"); + + ///////////////////////////////////////////// + // Segmented Light Guide commands + ///////////////////////////////////////////// + + addDirectory("/nDet/segLightGuide/","Segmented Light Guide Geometry"); + + addCommand(new G4UIcmdWithADouble("/nDet/segLightGuide/thickness",this)); + addGuidance("Defines the z thickness of the segmented light guide"); + + addCommand(new G4UIcmdWithADouble("/nDet/segLightGuide/frontLength",this)); + addGuidance("Defines the length (x dimension) of the front of the segmented light guide"); + + addCommand(new G4UIcmdWithADouble("/nDet/segLightGuide/frontWidth",this)); + addGuidance("Defines the width (y dimension) of the front of the segmented light guide"); + + addCommand(new G4UIcmdWithADouble("/nDet/segLightGuide/backLength",this)); + addGuidance("Defines the length (x dimension) of the back of the segmented light guide"); + + addCommand(new G4UIcmdWithADouble("/nDet/segLightGuide/backWidth",this)); + addGuidance("Defines the width (y dimension) of the back of the segmented light guide"); + + addCommand(new G4UIcmdWithAnInteger("/nDet/segLightGuide/segx",this)); + addGuidance("Defines the number of segments along the x direction"); + + addCommand(new G4UIcmdWithAnInteger("/nDet/segLightGuide/segy",this)); + addGuidance("Defines the number of segments along the y direction"); + + addCommand(new G4UIcmdWithAString("/nDet/segLightGuide/setWrapping", this)); + addGuidance("Set the material to use for reflective wrapping on the light guide"); } void nDetDetectorMessenger::SetNewChildValue(G4UIcommand* command, G4String newValue){ @@ -198,4 +319,137 @@ void nDetDetectorMessenger::SetNewChildValue(G4UIcommand* command, G4String newV G4double thickness = command->ConvertToDouble(newValue); fDetector->SetDetectorHeight(thickness*cm); } + + //For implant values + + else if(index == 26) { + fDetector->SetPmtDimension(newValue); + } + else if(index == 27) { + G4double length = command->ConvertToDouble(newValue); + fDetector->SetDetectorLength(length*cm); + } + else if(index == 28) { + G4double length = command->ConvertToDouble(newValue); + fDetector->SetDetectorWidth(length*cm); + } + else if(index == 29) { + G4double thickness = command->ConvertToDouble(newValue); + fDetector->SetDetectorHeight(thickness*mm); + } + else if(index == 30) { + G4double val = command->ConvertToDouble(newValue); + fDetector->SetMylarThickness(val*mm); + } + else if(index == 31) { + G4double val = command->ConvertToDouble(newValue); + fDetector->SetGreaseThickness(val*mm); + } + else if(index == 32) { + G4double val = command->ConvertToDouble(newValue); + fDetector->SetTrapezoidLength(val*cm); + } + else if(index == 33){ + G4int val = command->ConvertToInt(newValue); + fDetector->SetNumColumns(val); + } + else if(index == 34){ + G4int val = command->ConvertToInt(newValue); + fDetector->SetNumRows(val); + } + else if(index == 35){ + G4int val = command->ConvertToInt(newValue); + fDetector->SetNumPmtColumns(val); + } + else if(index == 36){ + G4int val = command->ConvertToInt(newValue); + fDetector->SetNumPmtRows(val); + } + else if(index == 37){ + G4double val = command->ConvertToDouble(newValue); + fDetector->SetDiffuserLength(val*cm); + } + else if(index == 38){ + fDetector->SetWrappingMaterial(newValue); + } + else if(index == 39){ + fDetector->SetDetectorMaterial(newValue); + } + else if(index == 40){ + G4ThreeVector val = command->ConvertToDimensioned3Vector(newValue); + fDetector->SetPosition(val); + } + else if(index == 41){ + G4ThreeVector val = command->ConvertTo3Vector(newValue); + fDetector->SetPositionCylindrical(val); + } + else if(index == 42){ + G4ThreeVector val = command->ConvertTo3Vector(newValue); + fDetector->SetPositionSpherical(val); + } + else if(index == 43){ + G4ThreeVector val = command->ConvertTo3Vector(newValue); + fDetector->SetRotation(val); + } + else if(index == 44) { + G4double val = command->ConvertToDouble(newValue); + fDetector->SetWindowThickness(val*mm); + } + else if(index == 45){ + fDetector->SetPolishedInterface((newValue == "true") ? true : false); + } + else if(index == 46){ + fDetector->SetAsStart(true); + } + else if(index == 47){ + fDetector->SetSquarePMTs((newValue == "true") ? true : false); + } + else if(index == 48){ + fDetector->SetSegmentWidth(command->ConvertToDouble(newValue)); + } + else if(index == 49){ + fDetector->SetSegmentHeight(command->ConvertToDouble(newValue)); + } + else if(index == 50){ + fDetector->SetTrapezoidAngle(command->ConvertToDouble(newValue)); + } + else if(index == 51) { + G4double thickness = command->ConvertToDouble(newValue); + fDetector->SetDetectorHeight(thickness*cm); + } + else if(index == 52){ + bool val = command->ConvertToBool(newValue); + std::cout<<"Setting Recon Logic to "<setReconLogic(val); + } + else if(index == 53){ + G4double val = command->ConvertToDouble(newValue); + fDetector->setSegZThick(val); + std::cout<<"Setting Z thickness to "<ConvertToDouble(newValue); + fDetector->setSegTopThick(val); + } + else if(index == 55){ + G4double val = command->ConvertToDouble(newValue); + fDetector->setSegTopWidth(val); + } + else if(index == 56){ + G4double val = command->ConvertToDouble(newValue); + fDetector->setSegBotThick(val); + } + else if(index == 57){ + G4double val = command->ConvertToDouble(newValue); + fDetector->setSegBotWidth(val); + } + else if(index == 58){ + G4int val = command->ConvertToInt(newValue); + fDetector->setSegX(val); + } + else if(index == 59){ + G4int val = command->ConvertToInt(newValue); + fDetector->setSegY(val); + } + else if(index == 60){} } diff --git a/source/nDetDetectorTypes.cc b/source/nDetDetectorTypes.cc index bdd8fb4..1288a48 100644 --- a/source/nDetDetectorTypes.cc +++ b/source/nDetDetectorTypes.cc @@ -27,6 +27,15 @@ nDetDetector* nDetDetectorTypes::getDetectorType(const G4String &geom){ return retval; } +nDetImplant* nDetDetectorTypes::getImplantType(const G4String &geom){ + nDetImplant *retval = NULL; + if(geom == "hagrid") + retval = new hagridType(); + else + retval = new implantType(); + return retval; +} + nDetDetector* nDetDetectorTypes::getDetectorType(const G4String &geom, nDetConstruction *construction, nDetMaterials *matptr){ nDetDetector *retval = NULL; if(geom == "next" || geom == "module") // Next module (segmented) @@ -40,6 +49,15 @@ nDetDetector* nDetDetectorTypes::getDetectorType(const G4String &geom, nDetConst return retval; } +nDetImplant* nDetDetectorTypes::getImplantType(const G4String &geom, nDetConstruction *construction, nDetMaterials *matptr){ + nDetImplant *retval = NULL; + if(geom == "hagrid") + retval = new hagridType(construction, matptr); + else + retval = new implantType(construction, matptr); + return retval; +} + /////////////////////////////////////////////////////////////////////////////// // class nextModuleType /////////////////////////////////////////////////////////////////////////////// @@ -309,3 +327,187 @@ void cylindricalType::buildDetector(){ layerSizeY = fDetectorHeight; offsetZ = fDetectorLength/2; } + +/////////////////////////////////////////////////////////////////////////////// +// class implantType +/////////////////////////////////////////////////////////////////////////////// + +void implantType::prepareToBuild(){ + // Set the maximum detector body size + maxBodySize = G4ThreeVector(fDetectorWidth, fDetectorHeight, fDetectorLength); +} + +void implantType::buildDetector(){ + const G4double cellWidth = GetSegmentWidth(); + const G4double cellHeight = GetSegmentHeight(); + + // Get the number of rows and columns for this segmented detector + int Ncol = fNumColumns; + int Nrow = fNumRows; + + // Update the detector's copy numbers + firstSegmentCopyNum = scintCopyNum; + lastSegmentCopyNum = firstSegmentCopyNum; //startCopyNum+col*row; + + // Construct the scintillator cell + G4Box *cellScint = new G4Box("scintillator", cellWidth/2, cellHeight/2, fDetectorLength/2); + G4LogicalVolume *cellScint_logV = new G4LogicalVolume(cellScint, scintMaterial, "scint_log"); + cellScint_logV->SetVisAttributes(scintVisAtt); + + G4Box *mylarVertLayer = NULL; + G4Box *mylarHorizLayer = NULL; + + G4LogicalVolume *mylarVertLayer_logV = NULL; + G4LogicalVolume *mylarHorizLayer_logV = NULL; + + // Build the wrapping. + G4PVPlacement *wrapping_physV = NULL; + G4PVPlacement* wrappingFacePhys = NULL; + if(WrappingEnabled()){ + // Construct the outer wrapping. + G4Box *wrappingBox = new G4Box("wrappingBox", fDetectorWidth/2+fWrappingThickness, fDetectorHeight/2+fWrappingThickness, fDetectorLength/2); + G4Box *scintBox = new G4Box("scintBox", fDetectorWidth/2, fDetectorHeight/2, fDetectorLength/2); + + G4SubtractionSolid *wrappingBody = new G4SubtractionSolid("wrapping", wrappingBox, scintBox); + G4LogicalVolume *wrapping_logV = new G4LogicalVolume(wrappingBody, outerMylar, "wrapping_logV"); + wrapping_logV->SetVisAttributes(wrappingVisAtt); + + // Place the outer wrapping into the assembly. + wrapping_physV = addToDetectorBody(wrapping_logV, "Wrapping"); + + auto wrappingFace = new G4Box("wrappingFace",fDetectorWidth/2+fWrappingThickness, fDetectorHeight/2+fWrappingThickness,fWrappingThickness/4.); + auto wrappingFace_log = new G4LogicalVolume(wrappingFace,outerMylar,"wrappingFace_log"); + wrappingFace_log->SetVisAttributes(windowVisAtt); + wrappingFacePhys = addFrontComponent(wrappingFace_log,-1*fDetectorLength/2-fWrappingThickness/4.,"wrappingFacePhys"); + + // Construct vertical and horizontal reflector layers for later use. + mylarVertLayer = new G4Box("mylarVertLayer", fWrappingThickness/2, fDetectorHeight/2, fDetectorLength/2); + mylarHorizLayer = new G4Box("mylarHorizLayer", cellWidth/2, fWrappingThickness/2, fDetectorLength/2); + + mylarVertLayer_logV = new G4LogicalVolume(mylarVertLayer, wrappingMaterial, "mylarVertLayer_logV"); + mylarHorizLayer_logV = new G4LogicalVolume(mylarHorizLayer, wrappingMaterial, "mylarHorizLayer_logV"); + + mylarVertLayer_logV->SetVisAttributes(wrappingVisAtt); + mylarHorizLayer_logV->SetVisAttributes(wrappingVisAtt); + } + + // Place the scintillator segments into the assembly. + std::vector mylarVertLayer_physV(Ncol, NULL); + std::vector > mylarHorizLayer_physV(Ncol, std::vector(Nrow, NULL)); + std::vector > cellScint_physV(Ncol, std::vector(Nrow, NULL)); + for(int col = 0; col < Ncol; col++){ + for(int row = 0; row < Nrow; row++){ + G4ThreeVector cellCenter(-fDetectorWidth/2 + col*fWrappingThickness + (col+0.5)*cellWidth, -fDetectorHeight/2 + row*fWrappingThickness + (row+0.5)*cellHeight, 0); + + // Copy numbers (segment IDs), indexed from 1 + std::stringstream stream; stream << "Scint-" << col << "," << row; + cellScint_physV[col][row] = addSegmentToBody(cellScint_logV, stream.str(), cellCenter); + scintBody_physV.push_back(cellScint_physV[col][row]); + + // Place vertical and horizontal reflectors. + if(WrappingEnabled()){ + if(row == 0 && col != Ncol-1){ // New vertical reflector layer. + std::stringstream stream2; stream2 << "Wrapping-" << col; + mylarVertLayer_physV[col] = addToDetectorBody(mylarVertLayer_logV, stream2.str().c_str(), G4ThreeVector(cellCenter.getX()+cellWidth/2+fWrappingThickness/2, 0, 0)); + } + if(row != Nrow-1){ // New horizontal reflector layer. + std::stringstream stream2; stream2 << "Wrapping-" << col << "," << row; + mylarHorizLayer_physV[col][row] = addToDetectorBody(mylarHorizLayer_logV, stream2.str().c_str(), G4ThreeVector(cellCenter.getX(), cellCenter.getY()+cellHeight/2+fWrappingThickness/2, 0)); + } + } + } + } + + // Define logical reflector surfaces. + if(WrappingEnabled()){ + std::cout<<"Wrapping the scintillator"<= 0 && leftCol < Ncol) // Left side vertical layer. + new G4LogicalBorderSurface("Wrapping", cellPhysical, mylarVertLayer_physV.at(col-1), wrappingOpSurf); + if(rightCol >= 0 && rightCol < Ncol) // Right side vertical layer. + new G4LogicalBorderSurface("Wrapping", cellPhysical, mylarVertLayer_physV.at(col), wrappingOpSurf); + if(downRow >= 0 && downRow < Nrow) // Bottom side horizontal layer. + new G4LogicalBorderSurface("Wrapping", cellPhysical, mylarHorizLayer_physV.at(col).at(row-1), wrappingOpSurf); + if(upRow >= 0 && upRow < Nrow) // Top side vertical layer. + new G4LogicalBorderSurface("Wrapping", cellPhysical, mylarHorizLayer_physV.at(col).at(row), wrappingOpSurf); + } + } + } + + // Update the scintillator copy number. + scintCopyNum += Nrow*Ncol; + + // Update the Z offset and layer width/height + layerSizeX = fDetectorWidth; + layerSizeY = fDetectorHeight; + offsetZ = fDetectorLength/2; +} + + + +/////////////////////////////////////////////////////////////////////////////// +// class hagridType +/////////////////////////////////////////////////////////////////////////////// + +void hagridType::prepareToBuild(){ + SetSquarePMTs(false); // Disable square PMTs + + // Set the maximum detector body size. Note here that X=Y=fDetectorWidth + maxBodySize = G4ThreeVector(fDetectorWidth, fDetectorWidth, fDetectorLength); +} + +void hagridType::buildDetector(){ + // Make sure the height and width match + fDetectorHeight = fDetectorWidth; + + G4Tubs *cylinderBody = new G4Tubs("scintBody", 0, fDetectorWidth/2, fDetectorLength/2, 0, 2*CLHEP::pi); + G4LogicalVolume *cylinderBody_logV = new G4LogicalVolume(cylinderBody, scintMaterial, "cylinderBody_logV"); + cylinderBody_logV->SetVisAttributes(scintVisAtt); + + // Place the scintillator inside the assembly. + G4PVPlacement *cylinderBody_physV = addToDetectorBody(cylinderBody_logV, "Scint"); + + scintBody_physV.push_back(cylinderBody_physV); + G4PVPlacement *wrapping_physV = NULL; + G4PVPlacement* wrappingFacePhys = NULL; + + // Build the wrapping. + if(WrappingEnabled()){ + std::cout<<"Wrapping Thickness: "<SetVisAttributes(wrappingVisAtt); + + // Place the wrapping around the scintillator. + G4PVPlacement *cylinderWrapping_physV = addToDetectorBody(cylinderWrapping_logV, "Wrapping"); + + auto wrappingFace = new G4Tubs("wrappingFace",0,fDetectorWidth/2+fWrappingThickness, fWrappingThickness/2,0,CLHEP::twopi); + auto wrappingFace_log = new G4LogicalVolume(wrappingFace,outerMylar,"wrappingFace_log"); + wrappingFace_log->SetVisAttributes(windowVisAtt); + wrappingFacePhys = addFrontComponent(wrappingFace_log,-1*fDetectorLength/2-fWrappingThickness/2.,"wrappingFacePhys"); + + // Reflective wrapping. + new G4LogicalBorderSurface("Wrapping", cylinderBody_physV, cylinderWrapping_physV, wrappingOpSurf); + } + + // Update the Z offset and layer width/height + layerSizeX = fDetectorWidth; + layerSizeY = fDetectorHeight; + offsetZ = fDetectorLength/2; +} \ No newline at end of file diff --git a/source/nDetMasterOutputFile.cc b/source/nDetMasterOutputFile.cc index e6f7bd3..120c229 100644 --- a/source/nDetMasterOutputFile.cc +++ b/source/nDetMasterOutputFile.cc @@ -59,6 +59,7 @@ nDetMasterOutputFile::nDetMasterOutputFile(){ evtData = new nDetEventStructure(); outData = new nDetOutputStructure(); + outImplantData = new nDetImplantOutputStructure(); multData = new nDetMultiOutputStructure(); debugData = new nDetDebugStructure(); traceData = new nDetTraceStructure(); @@ -70,6 +71,7 @@ nDetMasterOutputFile::~nDetMasterOutputFile(){ delete evtData; delete outData; + delete outImplantData; delete multData; delete debugData; delete traceData; @@ -162,6 +164,7 @@ bool nDetMasterOutputFile::openRootFile(const G4Run* aRun){ // Add the branches fTree->Branch("event", evtData); if(singleDetectorMode){ // Add the single-detector branches + fTree->Branch("implant", outImplantData); fTree->Branch("output", outData); if(outputDebug) // Add the debug branch fTree->Branch("debug", debugData); @@ -202,10 +205,11 @@ bool nDetMasterOutputFile::fillBranch(const nDetDataPack &pack){ fileLock.lock(); // Copy the data - pack.copyData(evtData, outData, multData, debugData, traceData); + pack.copyData(evtData, outData, outImplantData, multData, debugData, traceData); - if(outputBadEvents || pack.goodEvent()) + if(outputBadEvents || pack.goodEvent()){ fTree->Fill(); // Fill the tree + } double avgTimePerEvent; double avgTimePerPhoton; diff --git a/source/nDetMaterials.cc b/source/nDetMaterials.cc index a1bee9e..9127d1f 100644 --- a/source/nDetMaterials.cc +++ b/source/nDetMaterials.cc @@ -1,3 +1,4 @@ +#include #include "G4Element.hh" #include "G4Material.hh" #include "G4MaterialPropertiesTable.hh" @@ -23,6 +24,7 @@ nDetMaterials::~nDetMaterials(){ delete fGreaseOpSurf; delete fMylarOpSurf; delete fEsrOpSurf; + delete fAluminum; // Materials delete fGrease; @@ -46,6 +48,14 @@ nDetMaterials::~nDetMaterials(){ delete fEJ276; delete fEJ200MPT; delete fEJ276MPT; + delete fYSO; + delete fYSOMPT; + delete fLaBr3; + delete fLaBr3MPT; + delete fYAP; + delete fYAPMPT; + delete fGAGG; + delete fGAGGMPT; } delete messenger; } @@ -62,13 +72,21 @@ void nDetMaterials::initialize(){ elementList["F"] = fF; elementList["Si"] = fSi; elementList["Al"] = fAl; + elementList["Y"] = fY; + elementList["La"] = fLa; + elementList["Br"] = fBr; + elementList["Gd"] = fGd; + elementList["Ga"] = fGa; materialList["air"] = fAir; materialList["vacuum"] = fVacuum; materialList["teflon"] = fTeflon; - materialList["ej200"] = fEJ200; - materialList["ej276"] = fEJ276; + materialList["ej200"] = fEJ200; + materialList["ej276"] = fEJ276; materialList["grease"] = fGrease; + materialList["yso"] = fYSO; + materialList["labr3"] = fLaBr3; + materialList["yap"] = fYAP; materialList["quartz"] = fSiO2; materialList["silicon"] = fSilicon; materialList["mylar"] = fMylar; @@ -81,12 +99,17 @@ void nDetMaterials::initialize(){ opticalSurfaceList["esr"] = fEsrOpSurf; opticalSurfaceList["perfect"] = fPerfectOpSurf; opticalSurfaceList["grease"] = fGreaseOpSurf; + opticalSurfaceList["air"] = fAirOpSurf; + opticalSurfaceList["aluminum"] = fAluminumOpSurf; - //visAttributesList["air"] = &G4VisAttributes::Invisible; + visAttributesList["air"] = visWrapping; //visAttributesList["vacuum"] = &G4VisAttributes::Invisible; visAttributesList["teflon"] = visWrapping; visAttributesList["ej200"] = visScint; visAttributesList["ej276"] = visScint; + visAttributesList["yso"] = visScint; + visAttributesList["labr3"] = visScint; + visAttributesList["yap"] = visScint; visAttributesList["grease"] = visGrease; visAttributesList["quartz"] = visWindow; visAttributesList["silicon"] = visSensitive; @@ -123,12 +146,12 @@ G4OpticalSurface* nDetMaterials::getUserOpticalSurface(const G4String &name){ if(!opt) // Surface was not found std::cout << Display::ErrorStr("nDetDynamicMaterial") << "Optical surface named \"" << name << "\" was not found in list!\n" << Display::ResetStr(); - return opt; // default + return opt; // default } G4VisAttributes* nDetMaterials::getUserVisAttributes(const G4String &name){ G4VisAttributes *visatt = NULL; - if(name == "mylar" || name == "teflon" || name == "esr" || name == "perfect") + if(name == "mylar" || name == "teflon" || name == "esr" || name == "perfect" || "air") visatt = visWrapping; else visatt = getVisualAttributes(name); @@ -353,9 +376,22 @@ void nDetMaterials::defineMaterials(){ fF = nist.searchForElement("F"); fSi = nist.searchForElement("Si"); fAl = nist.searchForElement("Al"); + fY = nist.searchForElement("Y"); + fLa = nist.searchForElement("La"); + fBr = nist.searchForElement("Br"); + fGd = nist.searchForElement("Gd"); + fGa = nist.searchForElement("Ga"); // Air fAir = nist.searchForMaterial("G4_AIR"); + G4double airPhotonEnergy[2] = {2.*eV,3.*eV}; + G4double airRefIndex[2] = {1.0003,1.0003}; + G4double airAbsorption[2] = {1*m,1*m}; + fAirMPT = new G4MaterialPropertiesTable(); + fAirMPT->AddProperty("RINDEX",airPhotonEnergy,airRefIndex,2); + fAirMPT->AddProperty("ABSLENGTH",airPhotonEnergy,airAbsorption,2); + std::cout<<"Getting air absorption length "<GetProperty("RINDEX")<SetMaterialPropertiesTable(fAirMPT); // Lab vacuum fVacuum = nist.searchForMaterial("G4_Galactic"); @@ -462,7 +498,7 @@ void nDetMaterials::defineMaterials(){ // ACRYLIC (C5O2H8)n -- CRT ///////////////////////////////////////////////////////////////// - fAcrylic = nist.searchForMaterial("G4_PLEXIGLASS"); + fAcrylic = nist.searchForMaterial("G4_GLASS_PLATE"); // Photon energy (eV) G4double ENERGY_ACRYLIC[11] = {6.1992*eV, 4.95936*eV, 4.1328*eV, 3.5424*eV, 3.0996*eV, 2.7552*eV, 2.47968*eV, 2.25426*eV, 2.0664*eV, 1.90745*eV, 1.7712*eV}; @@ -482,6 +518,8 @@ void nDetMaterials::defineMaterials(){ G4double abslength[25] = {0, 0, 1.02102, 1.28345, 1.8604, 2.44271, 3.20801, 4.15751, 5.55214, 6.99127, 13.0334, 19.3961, 27.6547, 32.87, 34.1447, 35.5173, 34.1447, 32.87, 32.87, 34.1447, 34.1447, 35.5173, 35.5173, 34.1447, 33.7719}; + for(int i=0;i<(sizeof(abslength)/sizeof(abslength[0]));i++) + abslength[i] *=10.; MPT_Acrylic->AddProperty("ABSLENGTH", energy2, abslength, 25); fAcrylic->SetMaterialPropertiesTable(MPT_Acrylic); @@ -582,6 +620,19 @@ void nDetMaterials::defineMaterials(){ fGreaseOpSurf->SetModel(unified); // Defaults to Lambertian reflection (i.e. rough surface) --CRT fGreaseOpSurf->SetMaterialPropertiesTable(fGreaseMPT); + fAirOpSurf = new G4OpticalSurface("AirSurface"); + //fAirOpSurf->SetType; + //fAirOpSurf->SetFinish(polished); + //fAirOpSurf->SetModel(glisur); + fAirOpSurf->SetMaterialPropertiesTable(fAirMPT); + + fAluminumOpSurf = new G4OpticalSurface("PerfectReflector"); + fAluminumOpSurf->SetType(dielectric_metal); + fAluminumOpSurf->SetFinish(polished); + fAluminumOpSurf->SetModel(glisur); + fAluminumOpSurf->SetMaterialPropertiesTable(fAluminumMPT); + + isInitialized = true; } @@ -591,6 +642,10 @@ void nDetMaterials::defineScintillators(){ delete fEJ276; delete fEJ200MPT; delete fEJ276MPT; + delete fYSO; + delete fYSOMPT; + delete fLaBr3; + delete fLaBr3MPT; } ///////////////////////////////////////////////////////////////// @@ -709,10 +764,278 @@ void nDetMaterials::defineScintillators(){ fEJ276MPT->AddProperty("IONSCINTILLATIONYIELD", particleEnergy, ionYield_EJ276, 36)->SetSpline(true); fEJ276->SetMaterialPropertiesTable(fEJ276MPT); + + ///////////////////////////////////////////////////////////////// + // YSO Y2SiO5 + ///////////////////////////////////////////////////////////////// + + fYSO = new G4Material("YSO", 4.5*g/cm3, 3); + fYSO->AddElement(fY, 0.25); + fYSO->AddElement(fSi, 0.125); + fYSO->AddElement(fO, 0.625); + + G4double photonEnergy_YSO[44] = {2.004*eV, 2.058*eV, 2.112*eV, 2.166*eV, 2.220*eV, 2.274*eV, 2.328*eV, 2.382*eV, 2.436*eV, 2.490*eV, + 2.517*eV, 2.552*eV, 2.585*eV, 2.613*eV, 2.635*eV, 2.656*eV, 2.686*eV, 2.720*eV, 2.749*eV, 2.772*eV, + 2.791*eV, 2.809*eV, 2.826*eV, 2.842*eV, 2.861*eV, 2.884*eV, 2.919*eV, 2.946*eV, 2.954*eV, 2.961*eV, + 2.967*eV, 2.974*eV, 2.981*eV, 2.987*eV, 2.994*eV, 3.001*eV, 3.009*eV, 3.018*eV, 3.029*eV, 3.041*eV, + 3.056*eV, 3.083*eV, 3.137*eV, 3.191*eV}; + + G4double ScintilFast_YSO[44] = {0.000, 0.001, 0.001, 0.002, 0.003, 0.006, 0.010, 0.018, 0.033, 0.060, + 0.084, 0.122, 0.175, 0.234, 0.294, 0.356, 0.416, 0.473, 0.533, 0.594, + 0.657, 0.720, 0.784, 0.846, 0.903, 0.962, 1.000, 0.917, 0.857, 0.798, + 0.732, 0.669, 0.604, 0.542, 0.480, 0.422, 0.359, 0.297, 0.237, 0.170, + 0.105, 0.028, 0.004, 0.000}; + + //G4double photonEnergy_YSO[13] = {16.8179*keV, 23.0707*keV, 30.8922*keV, 50.0014*keV, 59.1033*keV, 80.4609*keV, 122.4170*keV, 280.3698*keV, 504.5552*keV, 659.8267*keV, 830.5057*keV, 1188.7809*keV, 1316.9683*keV}; + + //G4double ScintilFast_YSO[13] = {0.0482746, 0.0585062, 0.0648312, 0.0774812, 0.0748768, 0.0707841, 0.0776672, 0.0854804, 0.0878988, 0.0888289, 0.089387, 0.0880848, 0.0878988}; //This should be the efficiency curve..? + + //G4double electronYield_YSO[13] = {54.3455, 65.8639, 72.9843, 87.2251, 84.2932, 79.6859, 87.4346, 96.2304, 98.9529, 100, 100.628, 99.1623, 98.9529}; //I am not sure if this is the correct units + + G4double photonEnergy_YSO_2[2] = {16.8179*keV, 23.0707*keV}; + G4double RefIndex_YSO[2] = {1.80, 1.80}; //Data taken from https://www.advatech-uk.co.uk/yso_ce.html + G4double Absorption_YSO[2] = {2.57*cm, 2.57*cm}; // this is found in: Large size LSO:Ce and YSO:Ce scintillators for 50 MeV range /spl gamma/-ray detector + + fYSOMPT = new G4MaterialPropertiesTable(); + fYSOMPT->AddProperty("RINDEX", photonEnergy_YSO_2, RefIndex_YSO, 2); + fYSOMPT->AddProperty("ABSLENGTH", photonEnergy_YSO_2, Absorption_YSO, 2); + fYSOMPT->AddProperty("FASTCOMPONENT", photonEnergy_YSO, ScintilFast_YSO, 13); + + fYSOMPT->AddConstProperty("SCINTILLATIONYIELD", 24000/MeV); // Photon yield as found in paper above for 137Cs + fYSOMPT->AddConstProperty("RESOLUTIONSCALE", 1.0); // Intrinsic resolution + + fYSOMPT->AddConstProperty("FASTSCINTILLATIONRISETIME", 2.0*ns); + fYSOMPT->AddConstProperty("FASTTIMECONSTANT", 50.0*ns); + fYSOMPT->AddConstProperty("YIELDRATIO",1);// the strength of the fast component as a function of total scintillation yield + G4double particleEnergy_YSO[130]; + G4double electronYield_YSO[130]; + G4double protonYield_YSO[130]; + G4double ionYield_YSO[130]; + std::ifstream fin[3]; + fin[0].open("lightYieldYSO_electron.dat"); + fin[1].open("lightYieldYSO_proton.dat"); + fin[2].open("lightYieldYSO_024.dat"); + if(!fin[0].good()) + std::cout<<"!!!!! ERROR LOADING LIGHT YIELD FILES !!!!!!"<>en>>light; + electronYield_YSO[i] = light*pEF; + particleEnergy_YSO[i] = en*MeV; + fin[1]>>en>>light; + protonYield_YSO[i] = light*pEF; + fin[2]>>en>>light; + ionYield_YSO[i] = light*pEF; + } + + // G4double electronYield_YSO[36]; + // G4double protonYield_YSO[36]; + // G4double ionYield_YSO[36]; + + // Produce the scaled light-yield for YSO (scaled down from EJ200 by 14%). This will need to be adjusted for YSO as it has a different light yield than EJ276. + // for(size_t i = 0; i < 36; i++){ + // electronYield_YSO[i] = 0.86 * electronYield[i]; + // protonYield_YSO[i] = 0.86 * protonYield[i]; + // ionYield_YSO[i] = 0.86 * ionYield[i]; + // } + + fYSOMPT->AddProperty("ELECTRONSCINTILLATIONYIELD", particleEnergy_YSO, electronYield_YSO, 130)->SetSpline(true); + fYSOMPT->AddProperty("PROTONSCINTILLATIONYIELD", particleEnergy_YSO, protonYield_YSO, 130)->SetSpline(true); + fYSOMPT->AddProperty("IONSCINTILLATIONYIELD", particleEnergy_YSO, ionYield_YSO, 130)->SetSpline(true); + + fYSO->SetMaterialPropertiesTable(fYSOMPT); + + ///////////////////////////////////////////////////////////////// + // LaBr3 + ///////////////////////////////////////////////////////////////// + + fLaBr3 = new G4Material("LaBr3", 5.08*g/cm3, 2); + fLaBr3->AddElement(fLa, 0.25); + fLaBr3->AddElement(fBr, 0.75); + + G4double photonEnergy_LaBr3[44] = {2.004*eV, 2.058*eV, 2.112*eV, 2.166*eV, 2.220*eV, 2.274*eV, 2.328*eV, 2.382*eV, 2.436*eV, 2.490*eV, + 2.517*eV, 2.552*eV, 2.585*eV, 2.613*eV, 2.635*eV, 2.656*eV, 2.686*eV, 2.720*eV, 2.749*eV, 2.772*eV, + 2.791*eV, 2.809*eV, 2.826*eV, 2.842*eV, 2.861*eV, 2.884*eV, 2.919*eV, 2.946*eV, 2.954*eV, 2.961*eV, + 2.967*eV, 2.974*eV, 2.981*eV, 2.987*eV, 2.994*eV, 3.001*eV, 3.009*eV, 3.018*eV, 3.029*eV, 3.041*eV, + 3.056*eV, 3.083*eV, 3.137*eV, 3.191*eV}; + + G4double ScintilFast_LaBr3[44] = {0.000, 0.001, 0.001, 0.002, 0.003, 0.006, 0.010, 0.018, 0.033, 0.060, + 0.084, 0.122, 0.175, 0.234, 0.294, 0.356, 0.416, 0.473, 0.533, 0.594, + 0.657, 0.720, 0.784, 0.846, 0.903, 0.962, 1.000, 0.917, 0.857, 0.798, + 0.732, 0.669, 0.604, 0.542, 0.480, 0.422, 0.359, 0.297, 0.237, 0.170, + 0.105, 0.028, 0.004, 0.000}; + + G4double photonEnergy_LaBr3_2[2] = {2.004*eV, 3.191*eV}; + G4double RefIndex_LaBr3[2] = {1.90, 1.90}; + G4double Absorption_LaBr3[2] = {1.881*cm, 1.881*cm}; + + fLaBr3MPT = new G4MaterialPropertiesTable(); + fLaBr3MPT->AddProperty("RINDEX", photonEnergy_LaBr3_2, RefIndex_LaBr3, 2); + fLaBr3MPT->AddProperty("ABSLENGTH", photonEnergy_LaBr3_2, Absorption_LaBr3, 2); + fLaBr3MPT->AddProperty("FASTCOMPONENT", photonEnergy_LaBr3, ScintilFast_LaBr3, 44); + + fLaBr3MPT->AddConstProperty("SCINTILLATIONYIELD", 630000/MeV); + fLaBr3MPT->AddConstProperty("RESOLUTIONSCALE", 1.0); // Intrinsic resolution + + //fLaBr3MPT->AddConstProperty("RISETIMECONSTANT", 0.9*ns); Geant4 10.1 TODO + fLaBr3MPT->AddConstProperty("FASTSCINTILLATIONRISETIME", 0.9*ns); + fLaBr3MPT->AddConstProperty("FASTTIMECONSTANT", 2.1*ns); + fLaBr3MPT->AddConstProperty("YIELDRATIO",1);// the strength of the fast component as a function of total scintillation yield + + std::cout << "nDetConstruction: Photon yield is set to " << lightYieldScale << "x scale\n"; + + //light yield - data taken form V.V. Verbinski et al, Nucl. Instrum. & Meth. 65 (1968) 8-25 + G4double particleEnergy_LaBr3[36] = {1E-3, 0.10*MeV, 0.13*MeV, 0.17*MeV, 0.20*MeV, 0.24*MeV, 0.30*MeV, 0.34*MeV, 0.40*MeV, + 0.48*MeV, 0.60*MeV, 0.72*MeV, 0.84*MeV, 1.00*MeV, 1.30*MeV, 1.70*MeV, 2.00*MeV, 2.40*MeV, + 3.00*MeV, 3.40*MeV, 4.00*MeV, 4.80*MeV, 6.00*MeV, 7.20*MeV, 8.40*MeV, 10.00*MeV, 11.00*MeV, + 12.00*MeV, 13.00*MeV, 14.00*MeV, 15.00*MeV, 16.00*MeV, 17.00*MeV, 18.00*MeV, 19.00*MeV, 20.00*MeV}; + + G4double electronYield_LaBr3[36] = {0.0E+00*pEF, 1.0E+03*pEF, 1.3E+03*pEF, 1.7E+03*pEF, 2.0E+03*pEF, 2.4E+03*pEF, 3.0E+03*pEF, 3.4E+03*pEF, 4.0E+03*pEF, + 4.8E+03*pEF, 6.0E+03*pEF, 7.2E+03*pEF, 8.4E+03*pEF, 1.0E+04*pEF, 1.3E+04*pEF, 1.7E+04*pEF, 2.0E+04*pEF, 2.4E+04*pEF, + 3.0E+04*pEF, 3.4E+04*pEF, 4.0E+04*pEF, 4.8E+04*pEF, 6.0E+04*pEF, 7.2E+04*pEF, 8.4E+04*pEF, 1.0E+05*pEF, 1.1E+05*pEF, + 1.2E+05*pEF, 1.3E+05*pEF, 1.4E+05*pEF, 1.5E+05*pEF, 1.6E+05*pEF, 1.7E+05*pEF, 1.8E+05*pEF, 1.9E+05*pEF, 2.0E+05*pEF}; + + fLaBr3MPT->AddProperty("ELECTRONSCINTILLATIONYIELD", particleEnergy_LaBr3, electronYield_LaBr3, 36)->SetSpline(true); + G4double protonYield_LaBr3[36] = {0.6*pSF, 67.1*pSF, 88.6*pSF, 120.7*pSF, 146.5*pSF, 183.8*pSF, 246.0*pSF, 290.0*pSF, 365.0*pSF, + 483.0*pSF, 678.0*pSF, 910.0*pSF, 1175.0*pSF, 1562.0*pSF, 2385.0*pSF, 3660.0*pSF, 4725.0*pSF, 6250.0*pSF, + 8660.0*pSF, 10420.0*pSF, 13270.0*pSF, 17180.0*pSF, 23100.0*pSF, 29500.0*pSF, 36200.0*pSF, 45500.0*pSF, 51826.7*pSF, + 58313.7*pSF, 65047.2*pSF, 72027.4*pSF, 79254.2*pSF, 86727.6*pSF, 94447.6*pSF, 102414.2*pSF, 110627.4*pSF, 119087.2*pSF}; + + // fLaBr3MPT->AddProperty("PROTONSCINTILLATIONYIELD", particleEnergy_LaBr3, protonYield_LaBr3, 36)->SetSpline(true); + + G4double ionYield_LaBr3[36] = {0.2*pEF, 10.4*pEF, 12.7*pEF, 15.7*pEF, 17.9*pEF, 20.8*pEF, 25.1*pEF, 27.9*pEF, 31.9*pEF, + 36.8*pEF, 43.6*pEF, 50.2*pEF, 56.9*pEF, 65.7*pEF, 81.3*pEF, 101.6*pEF, 116.5*pEF, 136.3*pEF, + 166.2*pEF, 187.1*pEF, 218.6*pEF, 260.5*pEF, 323.5*pEF, 387.5*pEF, 451.5*pEF, 539.9*pEF, 595.5*pEF, + 651.8*pEF, 708.7*pEF, 766.2*pEF, 824.2*pEF, 882.9*pEF, 942.2*pEF, 1002.1*pEF, 1062.6*pEF, 1123.7*pEF}; + + // fLaBr3MPT->AddProperty("IONSCINTILLATIONYIELD", particleEnergy_LaBr3, ionYield_LaBr3, 36)->SetSpline(true); + + fLaBr3->SetMaterialPropertiesTable(fLaBr3MPT); + + + ///////////////////////////////////////////////////////////////// + // YAP YAlO3 + ///////////////////////////////////////////////////////////////// + + fYAP = new G4Material("YAP", 5.35*g/cm3, 3); + fYAP->AddElement(fY, 0.2); + fYAP->AddElement(fAl, 0.2); + fYAP->AddElement(fO, 0.6); + + G4double photonEnergy_YAP[44] = {2.004*eV, 2.058*eV, 2.112*eV, 2.166*eV, 2.220*eV, 2.274*eV, 2.328*eV, 2.382*eV, 2.436*eV, 2.490*eV, + 2.517*eV, 2.552*eV, 2.585*eV, 2.613*eV, 2.635*eV, 2.656*eV, 2.686*eV, 2.720*eV, 2.749*eV, 2.772*eV, + 2.791*eV, 2.809*eV, 2.826*eV, 2.842*eV, 2.861*eV, 2.884*eV, 2.919*eV, 2.946*eV, 2.954*eV, 2.961*eV, + 2.967*eV, 2.974*eV, 2.981*eV, 2.987*eV, 2.994*eV, 3.001*eV, 3.009*eV, 3.018*eV, 3.029*eV, 3.041*eV, + 3.056*eV, 3.083*eV, 3.137*eV, 3.191*eV}; + + G4double ScintilFast_YAP[44] = {0.000, 0.001, 0.001, 0.002, 0.003, 0.006, 0.010, 0.018, 0.033, 0.060, + 0.084, 0.122, 0.175, 0.234, 0.294, 0.356, 0.416, 0.473, 0.533, 0.594, + 0.657, 0.720, 0.784, 0.846, 0.903, 0.962, 1.000, 0.917, 0.857, 0.798, + 0.732, 0.669, 0.604, 0.542, 0.480, 0.422, 0.359, 0.297, 0.237, 0.170, + 0.105, 0.028, 0.004, 0.000}; + + //G4double photonEnergy_YAP[13] = {16.8179*keV, 23.0707*keV, 30.8922*keV, 50.0014*keV, 59.1033*keV, 80.4609*keV, 122.4170*keV, 280.3698*keV, 504.5552*keV, 659.8267*keV, 830.5057*keV, 1188.7809*keV, 1316.9683*keV}; + + //G4double ScintilFast_YAP[13] = {0.0482746, 0.0585062, 0.0648312, 0.0774812, 0.0748768, 0.0707841, 0.0776672, 0.0854804, 0.0878988, 0.0888289, 0.089387, 0.0880848, 0.0878988}; //This should be the efficiency curve..? + + //G4double electronYield_YAP[13] = {54.3455, 65.8639, 72.9843, 87.2251, 84.2932, 79.6859, 87.4346, 96.2304, 98.9529, 100, 100.628, 99.1623, 98.9529}; //I am not sure if this is the correct units + + G4double photonEnergy_YAP2[2] = {16.8179*keV, 23.0707*keV}; + G4double RefIndex_YAP[2] = {1.94,1.94}; + G4double Absorption_YAP[2] = {2.7*cm, 2.7*cm}; + + fYAPMPT = new G4MaterialPropertiesTable(); + fYAPMPT->AddProperty("RINDEX", photonEnergy_YAP2, RefIndex_YAP, 2); + fYAPMPT->AddProperty("ABSLENGTH", photonEnergy_YAP2, Absorption_YAP, 2); + fYAPMPT->AddProperty("FASTCOMPONENT", photonEnergy_YAP, ScintilFast_YAP, 44); + + fYAPMPT->AddConstProperty("SCINTILLATIONYIELD", 26000/MeV); + fYAPMPT->AddConstProperty("RESOLUTIONSCALE", 1.0); // Intrinsic resolution + + fYAPMPT->AddConstProperty("FASTSCINTILLATIONRISETIME", 2.0*ns); + fYAPMPT->AddConstProperty("FASTTIMECONSTANT", 50.0*ns); + fYAPMPT->AddConstProperty("YIELDRATIO",1);// the strength of the fast component as a function of total scintillation yield + + G4double electronYield_YAP[36]; + G4double protonYield_YAP[36]; + G4double ionYield_YAP[36]; + + // Produce the scaled light-yield for YAP (scaled down from EJ200 by 14%). This will need to be adjusted for YAP as it has a different light yield than EJ276. + for(size_t i = 0; i < 36; i++){ + electronYield_YAP[i] = 0.86 * electronYield[i]; + protonYield_YAP[i] = 0.86 * protonYield[i]; + ionYield_YAP[i] = 0.86 * ionYield[i]; + } + + fYAPMPT->AddProperty("ELECTRONSCINTILLATIONYIELD", particleEnergy, electronYield_YAP, 36)->SetSpline(true); + fYAPMPT->AddProperty("PROTONSCINTILLATIONYIELD", particleEnergy, protonYield_YAP, 36)->SetSpline(true); + fYAPMPT->AddProperty("IONSCINTILLATIONYIELD", particleEnergy, ionYield_YAP, 36)->SetSpline(true); + + fYAP->SetMaterialPropertiesTable(fYAPMPT); + + ///////////////////////////////////////////////////////////////// + // GAGG Gd3Al2Ga3O12 + ///////////////////////////////////////////////////////////////// + + fGAGG = new G4Material("GAGG", 6.63*g/cm3, 4); + fGAGG->AddElement(fGd, 0.15); + fGAGG->AddElement(fAl, 0.1); + fGAGG->AddElement(fGa, 0.15); + fGAGG->AddElement(fO, 0.6); + + G4double photonEnergy_GAGG[24] = {2.657150587*eV,2.602196113*eV,2.546601968*eV,2.515488356*eV,2.493333596*eV,2.468871385*eV,2.444884509*eV,2.418773247*eV,2.398282404*eV,2.370667847*eV,2.35098064*eV,2.32682673*eV,2.286884568*eV,2.237186055*eV,2.183269296*eV,2.135911364*eV,2.077142785*eV,2.058265389*eV,2.008969264*eV,1.953517553*eV,1.913896916*eV,1.868114944*eV,1.818611898*eV,1.775832214*eV}; + + G4double ScintilFast_GAGG[24] = {0.004895105,0.097202797,0.298601399,0.55034965,0.713986014,0.858741259,0.951048951,0.990909091,0.999300699,0.999300699,0.988811189,0.96993007,0.902797203,0.781118881,0.648951049,0.520979021,0.361538462,0.327972028,0.258741259,0.204195804,0.174825175,0.137062937,0.101398601,0.084615385}; + + //G4double photonEnergy_GAGG[13] = {16.8179*keV, 23.0707*keV, 30.8922*keV, 50.0014*keV, 59.1033*keV, 80.4609*keV, 122.4170*keV, 280.3698*keV, 504.5552*keV, 659.8267*keV, 830.5057*keV, 1188.7809*keV, 1316.9683*keV}; + + //G4double ScintilFast_GAGG[13] = {0.0482746, 0.0585062, 0.0648312, 0.0774812, 0.0748768, 0.0707841, 0.0776672, 0.0854804, 0.0878988, 0.0888289, 0.089387, 0.0880848, 0.0878988}; //This should be the efficiency curve..? + + //G4double electronYield_GAGG[13] = {54.3455, 65.8639, 72.9843, 87.2251, 84.2932, 79.6859, 87.4346, 96.2304, 98.9529, 100, 100.628, 99.1623, 98.9529}; //I am not sure if this is the correct units + + G4double photonEnergy_GAGG2[2] = {16.8179*keV, 23.0707*keV}; + G4double RefIndex_GAGG[2] = {1.9,1.9}; + G4double Absorption_GAGG[2] = {2.7*cm, 2.7*cm}; + + fGAGGMPT = new G4MaterialPropertiesTable(); + fGAGGMPT->AddProperty("RINDEX", photonEnergy_GAGG2, RefIndex_GAGG, 2); + fGAGGMPT->AddProperty("ABSLENGTH", photonEnergy_GAGG2, Absorption_GAGG, 2); + fGAGGMPT->AddProperty("FASTCOMPONENT", photonEnergy_GAGG, ScintilFast_GAGG, 24); + + fGAGGMPT->AddConstProperty("SCINTILLATIONYIELD", 30000/MeV); + fGAGGMPT->AddConstProperty("RESOLUTIONSCALE", 1.0); // Intrinsic resolution + + fGAGGMPT->AddConstProperty("FASTSCINTILLATIONRISETIME", 2.0*ns); + fGAGGMPT->AddConstProperty("FASTTIMECONSTANT", 50.0*ns); + fGAGGMPT->AddConstProperty("YIELDRATIO",1);// the strength of the fast component as a function of total scintillation yield + + G4double electronYield_GAGG[36]; + G4double protonYield_GAGG[36]; + G4double ionYield_GAGG[36]; + + // Produce the scaled light-yield for GAGG (scaled down from EJ200 by 14%). This will need to be adjusted for GAGG as it has a different light yield than EJ276. + for(size_t i = 0; i < 36; i++){ + electronYield_GAGG[i] = 0.86 * electronYield[i]; + protonYield_GAGG[i] = 0.86 * protonYield[i]; + ionYield_GAGG[i] = 0.86 * ionYield[i]; + } + + fGAGGMPT->AddProperty("ELECTRONSCINTILLATIONYIELD", particleEnergy, electronYield_GAGG, 36)->SetSpline(true); + fGAGGMPT->AddProperty("PROTONSCINTILLATIONYIELD", particleEnergy, protonYield_GAGG, 36)->SetSpline(true); + fGAGGMPT->AddProperty("IONSCINTILLATIONYIELD", particleEnergy, ionYield_GAGG, 36)->SetSpline(true); + + fGAGG->SetMaterialPropertiesTable(fGAGGMPT); + // Update the material dictionary materialList["ej200"] = fEJ200; materialList["ej276"] = fEJ276; + materialList["yso"] = fYSO; + materialList["labr3"] = fLaBr3; + materialList["yap"] = fYAP; + materialList["gagg"] = fGAGG; scintsAreDefined = true; } diff --git a/source/nDetParticleSource.cc b/source/nDetParticleSource.cc index c74f50e..ce84977 100644 --- a/source/nDetParticleSource.cc +++ b/source/nDetParticleSource.cc @@ -8,7 +8,6 @@ #include "cmcalc.hh" #include "termColors.hh" #include "optionHandler.hh" - #include "G4Event.hh" #include "G4GeneralParticleSource.hh" #include "G4ParticleTable.hh" @@ -17,6 +16,9 @@ #include "G4SystemOfUnits.hh" #include "G4Neutron.hh" #include "G4Gamma.hh" +#include "G4Alpha.hh" +#include "G4GenericIon.hh" +#include "G4IonTable.hh" #include "G4OpticalPhoton.hh" #include "G4Electron.hh" #include "Randomize.hh" @@ -38,7 +40,7 @@ nDetParticleSource &nDetParticleSource::getInstance(){ return instance; } -nDetParticleSource::nDetParticleSource(nDetDetector *det/*=NULL*/) : G4GeneralParticleSource(), fSourceMessenger(NULL), unitX(1,0,0), unitY(0,1,0), unitZ(0,0,1), +nDetParticleSource::nDetParticleSource(nDetDetector *det/*=NULL*/, nDetImplant *imp/*=NULL*/) : G4GeneralParticleSource(), fSourceMessenger(NULL), unitX(1,0,0), unitY(0,1,0), unitZ(0,0,1), sourceOrigin(0,0,0), beamspotType(0), beamspot(0), beamspot0(0), rot(), targThickness(0),targEnergyLoss(0), targTimeSlope(0), targTimeOffset(0), beamE0(0), useReaction(false), isotropic(false), back2back(false), realIsotropic(false), particleRxn(NULL), detPos(), detSize(), detRot(), sourceIndex(0), numSources(0), interpolationMethod("Lin") @@ -51,9 +53,12 @@ nDetParticleSource::nDetParticleSource(nDetDetector *det/*=NULL*/) : G4GeneralPa // Set the default particle reaction. particleRxn = new Reaction(); - - if(det) + if(det){ this->SetDetector(det); + } + else if(imp){ + this->SetImplant(imp); + } // Create a messenger for this class fSourceMessenger = new nDetParticleSourceMessenger(this); @@ -93,6 +98,7 @@ void nDetParticleSource::SetBeamEnergySigma(const G4double &energy, const G4doub void nDetParticleSource::SetSourcePosition(const G4ThreeVector &position){ G4SingleParticleSource *src; while( (src = nextSource()) ){ // Iterate over all defined sources + sourceOrigin = position; src->GetPosDist()->SetCentreCoords(position); } } @@ -130,8 +136,15 @@ bool nDetParticleSource::SetSourceType(const G4String &str){ std::string typeName = args.at(0); double beamEnergy = 1; + // Default ion to alpha particle + int mass = 4; + int charge = 2; if(Nargs >= 2) beamEnergy = strtod(args.at(1).c_str(), NULL); + if(Nargs >= 3){ + mass = atoi(args.at(2).c_str()); + charge = atoi(args.at(3).c_str()); + } // Set the type of source or beam if(typeName == "137Cs") @@ -148,6 +161,10 @@ bool nDetParticleSource::SetSourceType(const G4String &str){ Set252Cf(); else if(typeName == "neutron") SetNeutronBeam(beamEnergy); + else if(typeName == "alpha") + SetAlphaBeam(beamEnergy); + else if(typeName == "ion") + SetIonBeam(beamEnergy,mass,charge); else if(typeName == "gamma") SetGammaRayBeam(beamEnergy); else if(typeName == "laser"){ @@ -212,6 +229,12 @@ void nDetParticleSource::SetDetector(const nDetDetector *det){ detRot = det->GetDetectorRot(); } +void nDetParticleSource::SetImplant(const nDetImplant *imp){ + detPos = imp->GetDetectorPos(); + detSize = imp->GetDetectorSize(); + detRot = imp->GetDetectorRot(); +} + void nDetParticleSource::Set252Cf(const size_t &size_/*=150*/, const double &stepSize_/*=0.1*/){ Reset(); // Should this always clear the source? CRT @@ -297,11 +320,49 @@ void nDetParticleSource::Set90Sr(){ } void nDetParticleSource::SetNeutronBeam(const double &energy_){ + std::cout<<"Neutron Beam"<SetParticleDefinition(G4Neutron::NeutronDefinition()); SetBeamEnergy(energy_*MeV); } +void nDetParticleSource::SetAlphaBeam(const double &energy_){ + std::cout<<"Alpha Beam"<SetParticleDefinition(G4Alpha::AlphaDefinition()); + SetBeamEnergy(energy_*MeV); +} + +void nDetParticleSource::SetIonBeam(const double &energy_, const int &A, const int &Z, const double &exE/*=0.*/){ + std::cout<<"Ion Beam with A="< [energy(MeV)]" + std::vector args; + unsigned int Nargs = split_str(str, args); + if(Nargs < 1){ + Display::ErrorPrint("Invalid number of arguments given to ::SetSourceType().", "nDetParticleSource"); + Display::ErrorPrint(" SYNTAX: type [energy(MeV)]", "nDetParticleSource"); + return; + } + std::string typeName = args.at(0); + double beamEnergy = 1; + if(Nargs >= 2) + beamEnergy = strtod(args.at(1).c_str(), NULL); + + std::cout << " nDetParticleSource: Setting " <SetParticleDefinition(G4Implant::ImplantDefinition()); + GetCurrentSource()->SetParticleDefinition(G4Alpha::AlphaDefinition()); + SetBeamEnergy(beamEnergy*MeV); +}*/ + void nDetParticleSource::SetGammaRayBeam(const double &energy_){ Reset(); GetCurrentSource()->SetParticleDefinition(G4Gamma::GammaDefinition()); diff --git a/source/nDetParticleSourceMessenger.cc b/source/nDetParticleSourceMessenger.cc index a9bf838..17be143 100644 --- a/source/nDetParticleSourceMessenger.cc +++ b/source/nDetParticleSourceMessenger.cc @@ -65,25 +65,39 @@ void nDetParticleSourceMessenger::addAllCommands(){ addCommand(new G4UIcmdWithAString("/nDet/source/setGaussianEnergy", this)); addGuidance("Set the current energy level to a gaussian distribution and set the energy and sigma. SYNTAX: setGaussianEnergy "); + + addCommand(new G4UIcmdWith3Vector("/nDet/source/position", this)); // position of source + addGuidance("Set the position of the source by specifying angles about the x, y, and z axes"); + + // addCommand(new G4UIcmdWithAString("/nDet/source/ion", this)); + // addGuidance("Set a pre-defined isotropic ion particle source"); + // addGuidance("108Xe for Xenon-108 beam for implantation"); } void nDetParticleSourceMessenger::SetNewChildValue(G4UIcommand* command, G4String newValue){ size_t index; if(!findCommand(command, newValue, index)) return; - if(index == 0) + if(index == 0){ fAction->Print(G4UIcommand::ConvertToInt(newValue)); - else if(index == 1) + } + else if(index == 1){ fAction->SetSourceDirection(G4UIcommand::ConvertTo3Vector(newValue)); - else if(index == 2) + } + else if(index == 2){ fAction->SetSourceType(newValue); - else if(index == 3) + } + else if(index == 3){ fAction->SetBeamspotRadius(G4UIcommand::ConvertToDouble(newValue)); - else if(index == 4) + } + else if(index == 4){ fAction->SetBeamspotRadius0(G4UIcommand::ConvertToDouble(newValue)); - else if(index == 5) + } + else if(index == 5){ fAction->SetBeamspotType(newValue); - else if(index == 6) + } + else if(index == 6){ fAction->SetIsotropicMode(G4UIcommand::ConvertToInt(newValue)); + } else if(index == 7){ G4ThreeVector vec = G4UIcommand::ConvertTo3Vector(newValue); fAction->SetEnergyLimits(vec.getX(), vec.getY()); @@ -106,8 +120,13 @@ void nDetParticleSourceMessenger::SetNewChildValue(G4UIcommand* command, G4Strin else if(index == 13){ fAction->SetInterpolationMethod(newValue); } - else if(index == 14) + else if(index == 14){ fAction->SetBeamEnergy(G4UIcommand::ConvertToDouble(newValue)); - else if(index == 15) + } + else if(index == 15){ fAction->SetBeamEnergySigma(newValue); + } + else if(index==16){ + fAction->SetSourcePosition(G4UIcommand::ConvertTo3Vector(newValue)); + } } diff --git a/source/nDetRunAction.cc b/source/nDetRunAction.cc index c437b50..08ad882 100644 --- a/source/nDetRunAction.cc +++ b/source/nDetRunAction.cc @@ -13,12 +13,13 @@ #include "nDetSteppingAction.hh" #include "nDetParticleSource.hh" #include "nDetMasterOutputFile.hh" +#include "nDetDetector.hh" #include "termColors.hh" const double KINETIC_ENERGY_THRESHOLD = 0.03; // MeV std::default_random_engine generator; -std::normal_distribution distribution(6.551,0.7); +std::normal_distribution distribution(6.551,0.0); /// Returns the dot product of two vectors i.e. v1 * v2 double dotProduct(const G4ThreeVector &v1, const G4ThreeVector &v2){ @@ -116,7 +117,7 @@ nDetRunAction::nDetRunAction(){ detector = &nDetConstruction::getInstance(); // The detector builder is a singleton class. // Set data structure addresses. - data.setDataAddresses(&evtData, &outData, &multData, &debugData, &traceData); + data.setDataAddresses(&evtData, &outData, &outImplantData, &multData, &debugData, &traceData); } nDetRunAction::~nDetRunAction(){ @@ -163,6 +164,23 @@ void nDetRunAction::BeginOfRunAction(const G4Run* aRun) } outputFile->setMultiDetectorMode(true); } + else if(userImplants.size() > 1){ + if(outputFile->getOutputDebug()){ + Display::WarningPrint("Main debug output is not supported for more than one implant! Using reduced debug readout.", "nDetRunAction"); + outputFile->setOutputDebug((outputDebug = false)); + outputMultiDebug = true; + } + if(outputFile->getOutputTraces()){ + Display::WarningPrint("Trace output is not supported for more than one implant!", "nDetRunAction"); + outputFile->setOutputTraces((outputTraces = false)); + } + for(size_t index = 0; index < container->size(); index++){ // Set options per thread + container->getActionManager(index)->getRunAction()->setOutputDebug(false); + container->getActionManager(index)->getRunAction()->setOutputTraces(false); + container->getActionManager(index)->getRunAction()->setOutputMultiDebug(outputMultiDebug); + } + outputFile->setMultiDetectorMode(true); + } else{ // Single detector mode for(size_t index = 0; index < container->size(); index++){ // Set options per thread container->getActionManager(index)->getRunAction()->setOutputDebug(outputFile->getOutputDebug()); @@ -189,9 +207,11 @@ void nDetRunAction::EndOfRunAction(const G4Run* aRun) void nDetRunAction::updateDetector(nDetConstruction *construction){ // Clear all currently defined detectors userDetectors.clear(); + userImplants.clear(); // Copy the list of detectors construction->GetCopiesOfDetectors(userDetectors); + construction->GetCopiesOfImplants(userImplants); // Search for a start detector. Currently only one start is supported, break after finding the first one startDetector = NULL; @@ -200,6 +220,18 @@ void nDetRunAction::updateDetector(nDetConstruction *construction){ startDetector = &(*iter); break; } + else + endDetector=true; + } + + startImplant = NULL; + for(std::vector::iterator iter = userImplants.begin(); iter != userImplants.end(); iter++){ + if(iter->GetIsStart()){ + startImplant = &(*iter); + break; + } + else + endImplant=true; } } @@ -208,6 +240,11 @@ G4int nDetRunAction::checkCopyNumber(const G4int &num) const { if(iter->checkCopyNumber(num)) return iter->getParentCopyNumber(); } + + for(std::vector::const_iterator iter = userImplants.begin(); iter != userImplants.end(); iter++){ + if(iter->checkCopyNumber(num)) + return iter->getParentCopyNumber(); + } return -1; } @@ -216,6 +253,11 @@ bool nDetRunAction::getSegmentFromCopyNum(const G4int ©Num, G4int &col, G4in if(iter->getSegmentFromCopyNum(copyNum, col, row)) return true; } + + for(std::vector::const_iterator iter = userImplants.begin(); iter != userImplants.end(); iter++){ + if(iter->getSegmentFromCopyNum(copyNum, col, row)) + return true; + } return false; } @@ -263,6 +305,7 @@ bool nDetRunAction::processDetector(nDetDetector* det){ pmtResponse *pmtL = cmL->getPmtResponse(); pmtResponse *pmtR = cmR->getPmtResponse(); + //std::cout<<"!!! Process !!! "<GetCenterOfMass()->getNumColumns()<<" "<getNumColumns()<empty()) // No detected photons, do not process + return false; + + // Get the time offset due to straggling in the target (if applicable) + double targetTimeOffset = source->GetTargetTimeOffset(); + bool Ftrigger = false; + // Get pointers to the CoM calculators + params = detector->GetDetectorParameters(); + centerOfMass *cmI = imp->getCenterOfMass(); + //std::cout<<"!!! Process !!! "<GetCenterOfMass()->getNumColumns()<<" "<getNumColumns()<setSegmentedPmt(¶ms); + cmI->loadGainMatrix("hamamatsuH12700A_LA0967.dat"); + + debugData.nPhotons[0] += cmI->getNumDetected(); + + // Compute the total number of detected photons + outImplantData.nPhotonsDet += cmI->getNumDetected(); + + // Check for valid bar detection + if(cmI->getNumDetected() > 0) + evtData.goodEvent = true; + + // Compute the photon detection efficiency + outImplantData.nPhotonsTot = stacking->GetNumPhotonsProduced(); + if(outImplantData.nPhotonsTot > 0) + outImplantData.photonDetEff = outImplantData.nPhotonsDet/(double)outImplantData.nPhotonsTot; + else + outImplantData.photonDetEff = -1; + + // Get the photon center-of-mass positions + G4ThreeVector centerI = cmI->getCenter(); + debugData.photonDetComX[0] = centerI.getX(); + debugData.photonDetComY[0] = centerI.getY(); + //debugData.photonDetComZ[0] = centerI.getZ(); + + // Get photon arrival times at the PMTs + debugData.photonMinTime[0] = cmI->getMinArrivalTime(); + debugData.photonAvgTime[0] = cmI->getAvgArrivalTime(); + + pmtResponse *pmtI = cmI->getPmtResponse(); + + // The ADC clock is running continuously so the PMT signals may arrive at any time relative + // to the clock. To remove any inherent bias from this, we latch the ADCs at a random time + // in the range [-adcTick/2, +adcTick/2]. The pmtResponse class will automatically remove + // the latching time after running the CFD. + double latch = G4UniformRand()-0.5; // [-0.5, 0.5] + pmtI->setAdcLatchTicks(latch); + + // "Digitize" the light pulses. + pmtI->digitize(); + + // Check for saturated pulse. + if(pmtI->getPulseIsSaturated()){ + Display::WarningPrint("Implant PMT's traces have saturated! Recommend lowering the gain.", "nDetRunAction"); + } + + // Copy the trace into the trace vector. + if(outputTraces){ + pmtI->copyTrace(traceData.left); //This might be wrong + traceData.mult++; + } + + // Do some light pulse analysis + debugData.pulsePhase[0] = pmtI->analyzePolyCFD() + targetTimeOffset; + debugData.pulseQDC[0] = pmtI->integratePulseFromMaximum(); + debugData.pulseMax[0] = pmtI->getMaximum(); + debugData.pulseMaxTime[0] = pmtI->getMaximumTime(); + debugData.pulseArrival[0] = pmtI->getWeightedPhotonArrivalTime(); + + // Set Trigger boolean for events that would register in DAQ + if(pmtI->getTrigger() && abs(pmtI->getMaximumTime()) < 5) Ftrigger = true; + + // Print the digitized traces. + if(pmtI->getPrintTrace()){ + size_t traceLength = pmtI->getPulseLength(); + unsigned short *traceI = pmtI->getDigitizedPulse(); + std::cout << "***********************************************************\n"; + std::cout << "* PhotonsTot : " << outImplantData.nPhotonsTot << std::endl; + std::cout << "* PhotonsDet : " << outImplantData.nPhotonsDet << std::endl; + std::cout << "* MaxIndex : " << pmtI->getMaximumIndex() << std::endl; + std::cout << "* Baseline : " << pmtI->getBaseline() << std::endl; + std::cout << "* Maximum : " << pmtI->getMaximum() << std::endl; + std::cout << "* MaxTime : " << pmtI->getMaximumTime() << std::endl; + std::cout << "* WeightedArrival: " << pmtI->getWeightedPhotonArrivalTime() << std::endl; + std::cout << "* MinimumArrival : " << pmtI->getMinimumPhotonArrivalTime() << std::endl; + std::cout << "***********************************************************\n"; + + int adcClockTick = pmtI->getAdcClockInNanoseconds(); + for(size_t i = 0; i < traceLength; i++){ + std::cout << i*adcClockTick << "\t" << traceI[i] << std::endl; + } + } + + // Get the digitizer response of the anodes. + pmtResponse *anodeResponseI = cmI->getAnodeResponse(); + + // Digitize anode waveforms and integrate. + double anodeQDC[4]={0}; + for(size_t i = 0; i < 4; i++){ + anodeResponseI[i].digitize(); + debugData.anodeQDC[0][i] = anodeResponseI[i].integratePulseFromMaximum(); + anodeQDC[i] = debugData.anodeQDC[0][i]; + } + + // Compute the anode positions. + //debugData.reconDetComX[0] = -((anodeQDC[0]+anodeQDC[1])-(anodeQDC[2]+anodeQDC[3]))/(anodeQDC[0]+anodeQDC[1]+anodeQDC[2]+anodeQDC[3]); + //debugData.reconDetComY[0] = ((anodeQDC[1]+anodeQDC[2])-(anodeQDC[3]+anodeQDC[0]))/(anodeQDC[0]+anodeQDC[1]+anodeQDC[2]+anodeQDC[3]); + if(params.GetReconLogic()){ + debugData.reconDetComX[0] = cmI->getSipmX(); + debugData.reconDetComY[0] = cmI->getSipmY(); + } + else{ + debugData.reconDetComX[0] = cmI->getReconstructedX(); + debugData.reconDetComY[0] = cmI->getReconstructedY(); + } + //std::cout<<"recon "<getCenterSegment(debugData.centerOfMassColumn[0], debugData.centerOfMassRow[0]); + + // Update photon statistics. + numPhotonsTotal += outImplantData.nPhotonsTot; + numPhotonsDetTotal += outImplantData.nPhotonsDet; + + + return true; +} + bool nDetRunAction::processStartDetector(nDetDetector* det, double &startTime){ if(!processDetector(det)) // No detected photons, do not process return false; @@ -413,6 +631,19 @@ bool nDetRunAction::processStartDetector(nDetDetector* det, double &startTime){ return true; } +bool nDetRunAction::processStartImplant(nDetImplant* imp, double &startTime){ + //std::cout<<"!!! Start !!! "<GetCenterOfMass()->getNumColumns()<<" "<getCenterOfMass()->getNumColumns()<scatterEvent()){ } @@ -424,7 +655,37 @@ void nDetRunAction::process(){ } short detID = 0; - if(!startDetector){ // Un-triggered mode (default) + double startTime; + if(processStartDetector(startDetector, startTime)){ // Check for valid start signal + for(std::vector::iterator iter = userDetectors.begin(); iter != userDetectors.end(); iter++){ + // Skip the start detector because we already processed it + if(&(*iter) != startDetector && !processDetector(&(*iter))){ // Skip events with no detected photons + detID++; + continue; + } + + // Update the time-of-flight of the event + outData.barTOF = outData.barTOF - startTime; + + // Push data onto the output branch for multiple detectors + if(userDetectors.size() > 1) + multData.Append(outData, detID++); + } + } + else if(endImplant){ // Un-triggered mode (default) + for(std::vector::iterator iter = userImplants.begin(); iter != userImplants.end(); iter++){ + //std::cout<<"!!! End !!! "<GetCenterOfMass()->getNumColumns()<<" "<getCenterOfMass()->getNumColumns()< 1) + multData.Append(outImplantData, detID++); + } + } + else if(endDetector){ // Un-triggered mode (default) for(std::vector::iterator iter = userDetectors.begin(); iter != userDetectors.end(); iter++){ if(!processDetector(&(*iter))){ // Skip the start detector because we already processed it detID++; @@ -432,26 +693,27 @@ void nDetRunAction::process(){ } // Push data onto the output branch for multiple detectors - if(userDetectors.size() > 1) + if(userDetectors.size() > 1 || userImplants.size()>1) multData.Append(outData, detID++); } } + else{ // Start triggered mode - double startTime; - if(processStartDetector(startDetector, startTime)){ // Check for valid start signal - for(std::vector::iterator iter = userDetectors.begin(); iter != userDetectors.end(); iter++){ + if(processStartImplant(startImplant, startTime)){ // Check for valid start signal + for(std::vector::iterator iter = userImplants.begin(); iter != userImplants.end(); iter++){ + //std::cout<<"!!! Detector !!! "<GetCenterOfMass()->getNumColumns()<<" "<getCenterOfMass()->getNumColumns()< 1) - multData.Append(outData, detID++); + if(userImplants.size() > 1) + multData.Append(outImplantData, detID++); } } } @@ -470,6 +732,9 @@ void nDetRunAction::process(){ // Clear all statistics. for(std::vector::iterator iter = userDetectors.begin(); iter != userDetectors.end(); iter++) iter->clear(); + + for(std::vector::iterator iter = userImplants.begin(); iter != userImplants.end(); iter++) + iter->clear(); if(stacking) stacking->Reset(); if(tracking) tracking->Reset(); @@ -491,14 +756,15 @@ bool nDetRunAction::AddDetectedPhoton(const G4Step *step, const double &mass/*=1 Display::WarningPrint("INVALID POST POINT!", "nDetRunAction"); return false; } - + // Find which detector this optical photon is inside. G4int copyNum = step->GetPostStepPoint()->GetTouchable()->GetCopyNumber(); - bool foundMatch=false, isLeft; + bool foundMatch=false, isLeft=0, isImplant=0; G4ThreeVector *detPos; G4RotationMatrix *detRot; centerOfMass *hitDetPmtL; centerOfMass *hitDetPmtR; + centerOfMass *hitDetPmtI; for(std::vector::iterator iter = userDetectors.begin(); iter != userDetectors.end(); iter++){ if(iter->checkPmtCopyNumber(copyNum, isLeft)){ foundMatch = true; @@ -509,6 +775,15 @@ bool nDetRunAction::AddDetectedPhoton(const G4Step *step, const double &mass/*=1 break; } } + for(std::vector::iterator iter = userImplants.begin(); iter != userImplants.end(); iter++){ + if(iter->checkPmtCopyNumber(copyNum, isImplant)){ + foundMatch = true; + detPos = iter->getPosition(); + detRot = iter->getRotation(); + hitDetPmtI = iter->getCenterOfMass(); + break; + } + } if(!foundMatch){ Display::WarningPrint("Failed to find matching detector for detected photon?", "nDetRunAction"); @@ -524,8 +799,15 @@ bool nDetRunAction::AddDetectedPhoton(const G4Step *step, const double &mass/*=1 if(hitDetPmtL->addPoint(energy, time, position, mass)) return true; } - if(hitDetPmtR->addPoint(energy, time, position, mass)) - return true; + else if(isImplant){ + if(hitDetPmtI->addPoint(energy, time, position, mass)){ + return true; + } + } + else{ + if(hitDetPmtR->addPoint(energy, time, position, mass)) + return true; + } return false; } @@ -588,7 +870,9 @@ void nDetRunAction::initializeNeutron(const G4Step *step){ debugData.nEnterPosX = step->GetPostStepPoint()->GetPosition().getX(); debugData.nEnterPosY = step->GetPostStepPoint()->GetPosition().getY(); debugData.nEnterPosZ = step->GetPostStepPoint()->GetPosition().getZ(); - debugData.nTimeInMat = 0; + //debugData.nTimeInMat = 0; + //debugData.nTimeInMat = track->GetGlobalTime() - debugData.nEnterTime; + //debugData.nTimeInMat = track->GetGlobalTime(); //assuming particle enters at t=0 debugData.nExitPosX = 0; debugData.nExitPosY = 0; debugData.nExitPosZ = 0; diff --git a/source/nDetWorldObject.cc b/source/nDetWorldObject.cc index 425a07a..7c2ae72 100644 --- a/source/nDetWorldObject.cc +++ b/source/nDetWorldObject.cc @@ -392,6 +392,10 @@ void gdmlObject::construct(nDetDetector *obj){ obj->loadGDML(&solid); } +void gdmlObject::construct(nDetImplant *obj){ + obj->loadGDML(&solid); +} + std::string gdmlObject::syntaxStr() const { return std::string("loadGDML "); } diff --git a/source/nextSim.cc b/source/nextSim.cc index e0307ab..37e2a8b 100644 --- a/source/nextSim.cc +++ b/source/nextSim.cc @@ -163,7 +163,6 @@ int main(int argc, char** argv){ detector->BuildExp(expName); }else std::cout << "<<<<<<<<<<<<<<<<<<<< No experiment specified for \"-e\" argument. No setup will be constructed. >>>>>>>>>>>>>>>>>>>>\n"; - if(yieldMult > 0){ // Modify the photon yield of the detector std::cout << PROGRAM_NAME << ": Setting photon yield multiplier to " << yieldMult << std::endl; detector->SetLightYieldMultiplier(yieldMult); @@ -227,6 +226,7 @@ int main(int argc, char** argv){ G4String command = "/control/execute "; command += inputFilename; UImanager->ApplyCommand(command); + //std::cout<<"!! Detector !! "<GetCenterOfMass()->getNumColumns()<