From cb559861308787834e18bc9afa096137d6aaf8d5 Mon Sep 17 00:00:00 2001 From: icox2 Date: Wed, 10 Jun 2020 13:52:37 -0400 Subject: [PATCH 01/17] Added Implant detector --- dict/def.struct | 24 ++ dict/include/LinkDef.h | 1 + dict/include/nDetStructures.hpp | 57 ++++ dict/source/nDetStructures.cpp | 88 ++++++ include/nDetConstruction.hh | 33 ++ include/nDetDataPack.hh | 11 +- include/nDetDetector.hh | 371 +++++++++++++++++++++++ include/nDetDetectorLayer.hh | 9 + include/nDetDetectorTypes.hh | 36 +++ include/nDetMasterOutputFile.hh | 2 + include/nDetMaterials.hh | 3 + include/nDetParticleSource.hh | 15 +- include/nDetRunAction.hh | 30 ++ include/nDetWorldObject.hh | 14 + mac/next.mac | 6 +- mac/pspmt.mac | 128 ++++++++ source/CERNSupport.cc | 4 +- source/CloverQuadBuchDetector.cc | 2 +- source/CloverQuadDetector.cc | 6 +- source/CloverSingleBuchDetector.cc | 4 +- source/CloverSingleDetector.cc | 4 +- source/IS530_Chamber.cc | 4 +- source/IS530_Plastic.cc | 8 +- source/Polyhedron.cc | 260 ++++++++-------- source/nDetConstruction.cc | 138 ++++++++- source/nDetConstructionMessenger.cc | 76 +++++ source/nDetDataPack.cc | 7 +- source/nDetDetector.cc | 418 ++++++++++++++++++++++++++ source/nDetDetectorLayer.cc | 16 + source/nDetDetectorMessenger.cc | 185 ++++++++++++ source/nDetDetectorTypes.cc | 134 +++++++++ source/nDetMasterOutputFile.cc | 12 +- source/nDetMaterials.cc | 12 + source/nDetParticleSource.cc | 18 +- source/nDetParticleSourceMessenger.cc | 140 ++++++++- source/nDetRunAction.cc | 292 +++++++++++++++++- source/nDetWorldObject.cc | 4 + 37 files changed, 2383 insertions(+), 189 deletions(-) create mode 100644 mac/pspmt.mac diff --git a/dict/def.struct b/dict/def.struct index 47e5605..846d27d 100644 --- a/dict/def.struct +++ b/dict/def.struct @@ -57,6 +57,30 @@ 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_TYPES +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/nDetConstruction.hh b/include/nDetConstruction.hh index 1189fd8..0bb7c36 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(); @@ -164,6 +191,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 +208,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..be040f3 100644 --- a/include/nDetDetector.hh +++ b/include/nDetDetector.hh @@ -703,4 +703,375 @@ protected: G4CSGSolid *getLightGuideVolume(const G4String &name, const G4double &w1, const double &w2, const double &h1, const double &h2, const G4double &length); }; +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); + + /** 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); + +protected: + 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..97164ee 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 ; @@ -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 ; @@ -191,6 +198,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..8d30889 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,40 @@ 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: +}; + } // 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..ec9843d 100644 --- a/include/nDetMaterials.hh +++ b/include/nDetMaterials.hh @@ -32,6 +32,7 @@ class nDetMaterials{ G4Element* fF; ///< Flourine G4Element* fSi; ///< Silicon G4Element* fAl; ///< Aluminium + G4Element* fY; ///< Yttrium G4Material* fAir; ///< Material corresponding to air G4Material* fVacuum; ///< Material corresponding to natural vacuum @@ -44,6 +45,8 @@ class nDetMaterials{ G4Material* fMylar; ///< Material corresponding to aluminized mylar G4Material* fAcrylic; ///< Material corresponding to acrylic G4Material* fAluminum; ///< Material corresponding to aluminum + G4Material* fYSO; ///< Material corresponding to yttrium + // Material table properties G4MaterialPropertiesTable* fAirMPT; ///< Material properties table for air diff --git a/include/nDetParticleSource.hh b/include/nDetParticleSource.hh index 170658c..06daa85 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 @@ -319,7 +327,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 +398,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..8113944 100644 --- a/include/nDetRunAction.hh +++ b/include/nDetRunAction.hh @@ -174,6 +174,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 +192,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; } @@ -261,6 +273,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 +284,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 +301,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 +314,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/mac/next.mac b/mac/next.mac index b50b0c0..5959729 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 100 diff --git a/mac/pspmt.mac b/mac/pspmt.mac new file mode 100644 index 0000000..c4c717c --- /dev/null +++ b/mac/pspmt.mac @@ -0,0 +1,128 @@ +# +# 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.1 + +# Light diffuser. +#/nDet/implant/setDiffuserLength 0.5 + +# PMT segmentation. +/nDet/implant/setPmtColumns 8 +/nDet/implant/setPmtRows 8 + +################## +# DETECTOR SETUP # +################## + +# NEXT 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 + +# 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 + +# 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 + +# Update the detector. +/nDet/implant/update + +# 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 + +################ +# OUTPUT SETUP # +################ + +# Set the output filename prefix +/nDet/output/filename pspmt_test_1m.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/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 10000 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; igetPhysicalVolume()) + if(!expHall->getPhysicalVolume()){ this->ConstructDetector(); + this->ConstructImplant(); + } return expHall->getPhysicalVolume(); } @@ -70,14 +73,46 @@ 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 + //det->construct(); + 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 +138,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 +176,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 +251,65 @@ 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; } @@ -289,3 +416,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..314691b 100644 --- a/source/nDetConstructionMessenger.cc +++ b/source/nDetConstructionMessenger.cc @@ -114,6 +114,47 @@ 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"); + } void nDetConstructionMessenger::SetNewChildValue(G4UIcommand* command, G4String newValue){ @@ -247,5 +288,40 @@ 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->AddDetectorArray(newValue); + } + else if(index == 27){ + fDetector->PrintAllDetectors(); + } } } 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..fbf4f09 100644 --- a/source/nDetDetector.cc +++ b/source/nDetDetector.cc @@ -576,3 +576,421 @@ 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(false) +{ + copyCenterOfMass(*detector->GetCenterOfMass()); //This has been adjusted + materials = matptr; +} + +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::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); + wrappingVisAtt = materials->getUserVisAttributes(wrappingMaterialName); + wrappingOpSurf = materials->getUserOpticalSurface(wrappingMaterialName); + + // 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); + + // 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 += 2*(*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 *grease_physV[2] = {NULL, 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); + + //addMirroredComponents(grease_physV[0], grease_physV[1], grease_logV, greaseZ, "Grease"); + G4PVPlacement *greaseLogical = addBackComponent(grease_logV, greaseZ, "Grease"); //This might need to be edited for the distance... not sure how exactly one can automatically fit it to edge of detector.. maybe needs phys volume + + + if(!fPolishedInterface){ + for(std::vector::iterator iter = scintBody_physV.begin(); iter != scintBody_physV.end(); iter++){ + new G4LogicalBorderSurface("GreaseInterface", (*iter), grease_physV[0], materials->fGreaseOpSurf); + new G4LogicalBorderSurface("GreaseInterface", (*iter), grease_physV[1], materials->fGreaseOpSurf); + } + } + + // Clear all scintillator placements. + scintBody_physV.clear(); + } + + G4PVPlacement *window_physV[2] = {NULL, 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); + + //addMirroredComponents(window_physV[0], window_physV[1], window_logV, windowZ, "Quartz"); //not sure if this is needed + G4PVPlacement *window = 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[2]; + + if(grease_physV[0] && grease_physV[1]){ + new G4LogicalBorderSurface("Wrapping", grease_physV[0], greaseWrapping_physV[0], wrappingOpSurf); + new G4LogicalBorderSurface("Wrapping", grease_physV[1], greaseWrapping_physV[1], wrappingOpSurf); + } + if(window_physV[0] && window_physV[1]){ + new G4LogicalBorderSurface("Wrapping", window_physV[0], greaseWrapping_physV[0], wrappingOpSurf); + new G4LogicalBorderSurface("Wrapping", window_physV[1], greaseWrapping_physV[1], 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(){ + this->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, "Grease"); + + // 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::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; + 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..238ef5a 100644 --- a/source/nDetDetectorLayer.cc +++ b/source/nDetDetectorLayer.cc @@ -23,6 +23,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 +53,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,6 +85,10 @@ 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]"); } @@ -106,6 +118,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..8da87f1 100644 --- a/source/nDetDetectorMessenger.cc +++ b/source/nDetDetectorMessenger.cc @@ -97,6 +97,93 @@ 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"); } void nDetDetectorMessenger::SetNewChildValue(G4UIcommand* command, G4String newValue){ @@ -198,4 +285,102 @@ 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); + } } diff --git a/source/nDetDetectorTypes.cc b/source/nDetDetectorTypes.cc index bdd8fb4..9448494 100644 --- a/source/nDetDetectorTypes.cc +++ b/source/nDetDetectorTypes.cc @@ -27,6 +27,12 @@ nDetDetector* nDetDetectorTypes::getDetectorType(const G4String &geom){ return retval; } +nDetImplant* nDetDetectorTypes::getImplantType(const G4String &geom){ + nDetImplant *retval = NULL; + 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 +46,12 @@ nDetDetector* nDetDetectorTypes::getDetectorType(const G4String &geom, nDetConst return retval; } +nDetImplant* nDetDetectorTypes::getImplantType(const G4String &geom, nDetConstruction *construction, nDetMaterials *matptr){ + nDetImplant *retval = NULL; + retval = new implantType(construction, matptr); + return retval; +} + /////////////////////////////////////////////////////////////////////////////// // class nextModuleType /////////////////////////////////////////////////////////////////////////////// @@ -309,3 +321,125 @@ 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; + 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, wrappingMaterial, "wrapping_logV"); + wrapping_logV->SetVisAttributes(wrappingVisAtt); + + // Place the outer wrapping into the assembly. + wrapping_physV = addToDetectorBody(wrapping_logV, "Wrapping"); + + // 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()){ + for(int col = 0; col < Ncol; col++){ + for(int row = 0; row < Nrow; row++){ + G4PVPlacement *cellPhysical = cellScint_physV[col][row]; + + int leftCol = col-1; + int rightCol = col+1; + int downRow = row-1; + int upRow = row+1; + + // Border with the outer wrapping. + if((col == 0 || row == 0) || (col == Ncol-1 || row == Nrow-1)) + new G4LogicalBorderSurface("Wrapping", cellPhysical, wrapping_physV, wrappingOpSurf); + + // Internal reflector layers. + if(leftCol >= 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; +} + diff --git a/source/nDetMasterOutputFile.cc b/source/nDetMasterOutputFile.cc index e6f7bd3..92bbb3e 100644 --- a/source/nDetMasterOutputFile.cc +++ b/source/nDetMasterOutputFile.cc @@ -41,6 +41,7 @@ nDetMasterOutputFile::nDetMasterOutputFile(){ runIndex = 1; fFile = NULL; fTree = NULL; + fImpTree = NULL; runTitle = "NEXT Geant4 output"; runIndex = 1; @@ -59,6 +60,7 @@ nDetMasterOutputFile::nDetMasterOutputFile(){ evtData = new nDetEventStructure(); outData = new nDetOutputStructure(); + outImplantData = new nDetImplantOutputStructure(); multData = new nDetMultiOutputStructure(); debugData = new nDetDebugStructure(); traceData = new nDetTraceStructure(); @@ -70,6 +72,7 @@ nDetMasterOutputFile::~nDetMasterOutputFile(){ delete evtData; delete outData; + delete outImplantData; delete multData; delete debugData; delete traceData; @@ -158,10 +161,12 @@ bool nDetMasterOutputFile::openRootFile(const G4Run* aRun){ // Create root tree. if(treename.empty()) treename = "data"; //"neutronEvent"; fTree = new TTree(treename.c_str(), "Primary particle scattering data"); + fImpTree = new TTree("impData", "Data from the implant detector"); // 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); @@ -184,6 +189,7 @@ bool nDetMasterOutputFile::closeRootFile(){ if(fFile){ fFile->cd(); fTree->Write(); + fImpTree->Write(); fFile->Close(); delete fFile; fFile = NULL; @@ -202,10 +208,12 @@ 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 + fImpTree->Fill(); + } double avgTimePerEvent; double avgTimePerPhoton; diff --git a/source/nDetMaterials.cc b/source/nDetMaterials.cc index a1bee9e..07e626f 100644 --- a/source/nDetMaterials.cc +++ b/source/nDetMaterials.cc @@ -26,6 +26,7 @@ nDetMaterials::~nDetMaterials(){ // Materials delete fGrease; + delete fYSO; // Material properties tables delete fPerfectMPT; @@ -62,6 +63,7 @@ void nDetMaterials::initialize(){ elementList["F"] = fF; elementList["Si"] = fSi; elementList["Al"] = fAl; + elementList["Y"] = fY; materialList["air"] = fAir; materialList["vacuum"] = fVacuum; @@ -69,6 +71,7 @@ void nDetMaterials::initialize(){ materialList["ej200"] = fEJ200; materialList["ej276"] = fEJ276; materialList["grease"] = fGrease; + materialList["yso"] = fYSO; materialList["quartz"] = fSiO2; materialList["silicon"] = fSilicon; materialList["mylar"] = fMylar; @@ -353,12 +356,21 @@ void nDetMaterials::defineMaterials(){ fF = nist.searchForElement("F"); fSi = nist.searchForElement("Si"); fAl = nist.searchForElement("Al"); + fY = nist.searchForElement("Y"); // Air fAir = nist.searchForMaterial("G4_AIR"); // Lab vacuum fVacuum = nist.searchForMaterial("G4_Galactic"); + // YSO + + fYSO =new G4Material("YSO",2.7*g/cm3, 3); + fYSO->AddElement(fY,2); + fYSO->AddElement(fO,5); + fYSO->AddElement(fSi,1); + + materialList["yso"] = fYSO; ///////////////////////////////////////////////////////////////// // Teflon (C2F4)n diff --git a/source/nDetParticleSource.cc b/source/nDetParticleSource.cc index c74f50e..772b1eb 100644 --- a/source/nDetParticleSource.cc +++ b/source/nDetParticleSource.cc @@ -38,11 +38,12 @@ 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") { + std::cout<<"In Particle Source"<SetDetector(det); + std::cout<<"In Detector Source"<SetImplant(imp); + std::cout<<"In Implant Source"<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 diff --git a/source/nDetParticleSourceMessenger.cc b/source/nDetParticleSourceMessenger.cc index a9bf838..747f10c 100644 --- a/source/nDetParticleSourceMessenger.cc +++ b/source/nDetParticleSourceMessenger.cc @@ -70,20 +70,27 @@ void nDetParticleSourceMessenger::addAllCommands(){ 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 +113,123 @@ 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); + } +} + +/*void nDetImplantParticleSourceMessenger::addAllCommands(){ + addDirectory("/nDet/source/", "Particle Source Control"); + + G4UIcmdWithAnInteger *cmd = new G4UIcmdWithAnInteger("/nDet/source/sample", this); + cmd->SetParameterName("Nsamples", true); + cmd->SetGuidance("Test distribution by outputting a random energy"); + cmd->SetDefaultValue(1); + addCommand(cmd); // test function + + addCommand(new G4UIcmdWith3Vector("/nDet/source/direction", this)); // direction of source + addGuidance("Set the direction of the source by specifying angles about the x, y, and z axes (in deg)"); + + addCommand(new G4UIcmdWithAString("/nDet/source/type", this)); // type of source (252Cf, 137Cs, etc) + addGuidance("Set a pre-defined isotropic particle source"); + addGuidance("252Cf 137Cs 60Co 133Ba 241Am 90Sr neutron gamma electron laser"); + + addCommand(new G4UIcmdWithADouble("/nDet/source/spot", this)); // beamspot radius (mm) + addGuidance("Set the radius of the beam (in mm)"); + + addCommand(new G4UIcmdWithADouble("/nDet/source/spot0", this)); // beamspot radius (mm) + addGuidance("Set the secondary radius of the beam (in mm)"); + + addCommand(new G4UIcmdWithAString("/nDet/source/shape", this)); // beamspot shape type + addGuidance("Set the shape of the beamspot"); + addCandidates("point circle annulus ellipse square rectangle vertical horizontal gauss"); + + addCommand(new G4UIcmdWithAnInteger("/nDet/source/iso", this)); + addGuidance("Set the source isotropic mode (0=off, 1=psuedo, 2=realistic)"); + + addCommand(new G4UIcmdWith3Vector("/nDet/source/range", this)); + addGuidance("Set the energy range of a continuous distribution source"); + + addCommand(new G4UIcmdWithAString("/nDet/source/reaction", this)); + addGuidance("Load a reaction file. SYNTAX: reaction "); + + addCommand(new G4UIcmdWithAString("/nDet/source/edist", this)); + addGuidance("Read the source energy distribution from an ascii file. SYNTAX: edist "); + + addCommand(new G4UIcmdWithAString("/nDet/source/addLevel", this)); + addGuidance("Add a discrete energy level to the current source. SYNTAX: addLevel [intensity] [particle]"); + + addCommand(new G4UIcmdWithAString("/nDet/source/test", this)); + addGuidance("Simulate a specified number of events and write particle energies to an output file. SYNTAX: test "); + + addCommand(new G4UIcmdWithoutParameter("/nDet/source/reset", this)); + addGuidance("Reset the source and clear all defined energy levels"); + + addCommand(new G4UIcmdWithAString("/nDet/source/inter", this)); + addGuidance("Set the default interpolation method for user defined energy distributions"); + addCandidates("Lin Log Exp Spline"); + + addCommand(new G4UIcmdWithADouble("/nDet/source/setEnergy", this)); + addGuidance("Set the current energy level to mono-energetic and set the energy (in MeV)"); + + 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 "); +} + +void nDetImplantParticleSourceMessenger::SetNewChildValue(G4UIcommand* command, G4String newValue){ + size_t index; + if(!findCommand(command, newValue, index)) return; + if(index == 0){ + fActionI->Print(G4UIcommand::ConvertToInt(newValue)); + } + else if(index == 1){ + fActionI->SetSourceDirection(G4UIcommand::ConvertTo3Vector(newValue)); + } + else if(index == 2){ + fActionI->SetSourceType(newValue); + } + else if(index == 3){ + fActionI->SetBeamspotRadius(G4UIcommand::ConvertToDouble(newValue)); + } + else if(index == 4){ + fActionI->SetBeamspotRadius0(G4UIcommand::ConvertToDouble(newValue)); + } + else if(index == 5){ + fActionI->SetBeamspotType(newValue); + } + else if(index == 6){ + fActionI->SetIsotropicMode(G4UIcommand::ConvertToInt(newValue)); + } + else if(index == 7){ + G4ThreeVector vec = G4UIcommand::ConvertTo3Vector(newValue); + fActionI->SetEnergyLimits(vec.getX(), vec.getY()); + } + else if(index == 8){ + fActionI->ReadReactionFile(newValue); + } + else if(index == 9){ + fActionI->ReadEnergyFile(newValue); + } + else if(index == 10){ + fActionI->AddDiscreteEnergy(newValue); + } + else if(index == 11){ + fActionI->Test(newValue); + } + else if(index == 12){ + fActionI->Reset(); + } + else if(index == 13){ + fActionI->SetInterpolationMethod(newValue); + } + else if(index == 14){ + fActionI->SetBeamEnergy(G4UIcommand::ConvertToDouble(newValue)); + } + else if(index == 15){ + fActionI->SetBeamEnergySigma(newValue); + } } +*/ \ No newline at end of file diff --git a/source/nDetRunAction.cc b/source/nDetRunAction.cc index c437b50..84eaedf 100644 --- a/source/nDetRunAction.cc +++ b/source/nDetRunAction.cc @@ -116,7 +116,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 +163,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 +206,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 +219,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 +239,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 +252,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; } @@ -403,6 +444,172 @@ bool nDetRunAction::processDetector(nDetDetector* det){ return true; } +bool nDetRunAction::processImplant(nDetImplant* imp){ + if(!imp || imp->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 + centerOfMass *cmI = imp->getCenterOfMass(); + + 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] = centerL.getZ(); debugData.photonDetComZ[1] = centerR.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 *anodeResponseL = cmL->getAnodeResponse(); + pmtResponse *anodeResponseR = cmR->getAnodeResponse(); + + // Digitize anode waveforms and integrate. + float anodeQDC[2][4]; + for(size_t i = 0; i < 4; i++){ + anodeResponseL[i].digitize(); + anodeResponseR[i].digitize(); + debugData.anodeQDC[0][i] = anodeResponseL[i].integratePulseFromMaximum(); + debugData.anodeQDC[1][i] = anodeResponseR[i].integratePulseFromMaximum(); + } + + // Compute the anode positions. + for(size_t i = 0; i < 2; i++){ + debugData.reconDetComX[i] = -((anodeQDC[i][0]+anodeQDC[i][1])-(anodeQDC[i][2]+anodeQDC[i][3]))/(anodeQDC[i][0]+anodeQDC[i][1]+anodeQDC[i][2]+anodeQDC[i][3]); + debugData.reconDetComY[i] = ((anodeQDC[i][1]+anodeQDC[i][2])-(anodeQDC[i][3]+anodeQDC[i][0]))/(anodeQDC[i][0]+anodeQDC[i][1]+anodeQDC[i][2]+anodeQDC[i][3]); + } + outImplantData.reconComX = (debugData.reconDetComX[0] + debugData.reconDetComX[1]) / 2; + outImplantData.reconComY = (debugData.reconDetComY[0] + debugData.reconDetComY[1]) / 2;*/ + + if(outputDebug || outputMultiDebug){ + // Perform CFD on digitized anode waveforms. + /*for(size_t i = 0; i < 4; i++){ + debugData.anodePhase[0][i] = anodeResponseL[i].analyzePolyCFD() + targetTimeOffset; // left + debugData.anodePhase[1][i] = anodeResponseR[i].analyzePolyCFD() + targetTimeOffset; // right + }*/ + + G4ThreeVector nCenterMass(debugData.nComX, debugData.nComY, debugData.nComZ); + G4ThreeVector nIncidentPos(debugData.nEnterPosX, debugData.nEnterPosY, debugData.nEnterPosZ); + G4ThreeVector nExitPos(debugData.nExitPosX, debugData.nExitPosY, debugData.nExitPosZ); + + // Compute the neutron scatter center-of-mass. + nCenterMass = (1/debugData.neutronWeight)*nCenterMass; + + // Convert the neutron incident/exit positions to the frame of the detector. + nIncidentPos = nIncidentPos; + nExitPos = nExitPos; + + // Now in the rotated frame of the detector. + debugData.nComX = nCenterMass.getX(); + debugData.nComY = nCenterMass.getY(); + debugData.nComZ = nCenterMass.getZ(); + debugData.nEnterPosX = nIncidentPos.getX(); + debugData.nEnterPosY = nIncidentPos.getY(); + debugData.nEnterPosZ = nIncidentPos.getZ(); + debugData.nExitPosX = nExitPos.getX(); + debugData.nExitPosY = nExitPos.getY(); + debugData.nExitPosZ = nExitPos.getZ(); + } + + // Compute the light balance (Z). + outImplantData.lightBalance = (debugData.pulseQDC[0]-debugData.pulseQDC[1])/(debugData.pulseQDC[0]+debugData.pulseQDC[1]); + outImplantData.tdiff = (debugData.pulsePhase[0]-debugData.pulsePhase[1]); + outImplantData.photonTdiff = (debugData.photonAvgTime[0] - debugData.photonAvgTime[1]); + + // Compute "bar" variables. + double offset = distribution(generator); + outImplantData.barTOF = (debugData.pulsePhase[0]+debugData.pulsePhase[1])/2-offset; + outImplantData.barQDC = std::sqrt(debugData.pulseQDC[0]*debugData.pulseQDC[1]); + outImplantData.barMaxADC = std::sqrt(abs(debugData.pulseMax[0])*abs(debugData.pulseMax[1])); + outImplantData.barTrig = Ftrigger; + outImplantData.photonTOF = (debugData.photonAvgTime[0]+debugData.photonAvgTime[1])/2.0-offset; + outImplantData.photonComX = (debugData.photonDetComX[0] + debugData.photonDetComX[1]) / 2; + outImplantData.photonComY = (debugData.photonDetComY[0] + debugData.photonDetComY[1]) / 2; + // Get the segment of the detector where the photon CoM occurs. + cmI->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 +620,17 @@ bool nDetRunAction::processStartDetector(nDetDetector* det, double &startTime){ return true; } +bool nDetRunAction::processStartImplant(nDetImplant* imp, double &startTime){ + if(!processImplant(imp)){ // No detected photons, do not process + return false; + } + + // Return the time-of-flight from the start detector + startTime = outImplantData.barTOF; + + return true; +} + void nDetRunAction::process(){ while(this->scatterEvent()){ } @@ -424,7 +642,36 @@ 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++){ + if(!processImplant(&(*iter))){ // Skip the start detector because we already processed it + detID++; + continue; + } + + // Push data onto the output branch for multiple detectors + if(userImplants.size() > 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++; @@ -436,22 +683,22 @@ void nDetRunAction::process(){ 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++){ // Skip the start detector because we already processed it - if(&(*iter) != startDetector && !processDetector(&(*iter))){ // Skip events with no detected photons + if(&(*iter) != startImplant && !processImplant(&(*iter))){ // Skip events with no detected photons detID++; continue; } // Update the time-of-flight of the event - outData.barTOF = outData.barTOF - startTime; + outImplantData.barTOF = outImplantData.barTOF - startTime; // Push data onto the output branch for multiple detectors - if(userDetectors.size() > 1) - multData.Append(outData, detID++); + if(userImplants.size() > 1) + multData.Append(outImplantData, detID++); } } } @@ -470,6 +717,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 +741,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 +760,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 +784,14 @@ 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; } 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 "); } From e83f4675737b880e29a54bd68be68e8ce3b42138 Mon Sep 17 00:00:00 2001 From: icox2 Date: Thu, 18 Jun 2020 10:31:57 -0400 Subject: [PATCH 02/17] Adding YSO with plactic scint. properties --- gain/distortionTest.dat | 8 ++ include/nDetMaterials.hh | 1 + mac/multi.mac | 155 +++++++++++++++++++++++++++++++++ mac/pspmt.mac | 11 ++- source/nDetDetector.cc | 2 +- source/nDetMasterOutputFile.cc | 4 - source/nDetMaterials.cc | 71 ++++++++++++++- 7 files changed, 240 insertions(+), 12 deletions(-) create mode 100644 gain/distortionTest.dat create mode 100644 mac/multi.mac diff --git a/gain/distortionTest.dat b/gain/distortionTest.dat new file mode 100644 index 0000000..cbdc19c --- /dev/null +++ b/gain/distortionTest.dat @@ -0,0 +1,8 @@ +78 80 85 88 89 81 89 96 +77 50 50 95 96 93 91 98 +77 50 50 91 92 83 84 96 +78 69 82 95 97 86 83 94 +78 70 80 92 97 84 83 95 +75 71 79 89 99 85 81 95 +70 77 81 87 100 92 96 93 +72 73 74 80 90 93 99 92 diff --git a/include/nDetMaterials.hh b/include/nDetMaterials.hh index ec9843d..61ce458 100644 --- a/include/nDetMaterials.hh +++ b/include/nDetMaterials.hh @@ -53,6 +53,7 @@ class nDetMaterials{ 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* fGreaseMPT; ///< Material properties table for optical grease G4MaterialPropertiesTable* fSiO2MPT; ///< Material properties table for quartz G4MaterialPropertiesTable* fSiliconMPT; ///< Material properties table for silicon 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/pspmt.mac b/mac/pspmt.mac index c4c717c..a265405 100644 --- a/mac/pspmt.mac +++ b/mac/pspmt.mac @@ -21,7 +21,10 @@ /nDet/implant/setGreaseThickness 0.1 # Light diffuser. -#/nDet/implant/setDiffuserLength 0.5 +/nDet/implant/setDiffuserLength 1.5 + +# Choose Scintillator +/nDet/implant/setMaterial yso # PMT segmentation. /nDet/implant/setPmtColumns 8 @@ -59,7 +62,7 @@ # 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 +/nDet/implant/setGainMatrix gains/distortionTest.dat # Load PSPMT spectral response function /nDet/implant/setSpectralResponse spectral/hamamatsuH12700A.root @@ -69,7 +72,7 @@ ################ # Set the output filename prefix -/nDet/output/filename pspmt_test_1m.root +/nDet/output/filename distortion_test_1m.root /nDet/output/title PSPMT, 0.5 MeV, 1 m from detector #/nDet/output/index 69 #/nDet/output/overwrite true @@ -125,4 +128,4 @@ # RUN CONTROL # ############### -/run/beamOn 10000 +/run/beamOn 1000 diff --git a/source/nDetDetector.cc b/source/nDetDetector.cc index fbf4f09..a6ff24a 100644 --- a/source/nDetDetector.cc +++ b/source/nDetDetector.cc @@ -976,7 +976,7 @@ void nDetImplant::loadLightGuide(gdmlSolid *solid, const G4ThreeVector &rotation // Set internal reflectors solid->setLogicalBorders("InnerWrapping", materials->fEsrOpSurf); - G4double trapezoidZ = offsetZ + solid->getLength()/2; + 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. diff --git a/source/nDetMasterOutputFile.cc b/source/nDetMasterOutputFile.cc index 92bbb3e..120c229 100644 --- a/source/nDetMasterOutputFile.cc +++ b/source/nDetMasterOutputFile.cc @@ -41,7 +41,6 @@ nDetMasterOutputFile::nDetMasterOutputFile(){ runIndex = 1; fFile = NULL; fTree = NULL; - fImpTree = NULL; runTitle = "NEXT Geant4 output"; runIndex = 1; @@ -161,7 +160,6 @@ bool nDetMasterOutputFile::openRootFile(const G4Run* aRun){ // Create root tree. if(treename.empty()) treename = "data"; //"neutronEvent"; fTree = new TTree(treename.c_str(), "Primary particle scattering data"); - fImpTree = new TTree("impData", "Data from the implant detector"); // Add the branches fTree->Branch("event", evtData); @@ -189,7 +187,6 @@ bool nDetMasterOutputFile::closeRootFile(){ if(fFile){ fFile->cd(); fTree->Write(); - fImpTree->Write(); fFile->Close(); delete fFile; fFile = NULL; @@ -212,7 +209,6 @@ bool nDetMasterOutputFile::fillBranch(const nDetDataPack &pack){ if(outputBadEvents || pack.goodEvent()){ fTree->Fill(); // Fill the tree - fImpTree->Fill(); } double avgTimePerEvent; diff --git a/source/nDetMaterials.cc b/source/nDetMaterials.cc index 07e626f..49b63f0 100644 --- a/source/nDetMaterials.cc +++ b/source/nDetMaterials.cc @@ -26,7 +26,6 @@ nDetMaterials::~nDetMaterials(){ // Materials delete fGrease; - delete fYSO; // Material properties tables delete fPerfectMPT; @@ -47,6 +46,8 @@ nDetMaterials::~nDetMaterials(){ delete fEJ276; delete fEJ200MPT; delete fEJ276MPT; + delete fYSO; + delete fYSOMPT; } delete messenger; } @@ -90,6 +91,7 @@ void nDetMaterials::initialize(){ visAttributesList["teflon"] = visWrapping; visAttributesList["ej200"] = visScint; visAttributesList["ej276"] = visScint; + visAttributesList["yso"] = visScint; visAttributesList["grease"] = visGrease; visAttributesList["quartz"] = visWindow; visAttributesList["silicon"] = visSensitive; @@ -365,12 +367,12 @@ void nDetMaterials::defineMaterials(){ fVacuum = nist.searchForMaterial("G4_Galactic"); // YSO - fYSO =new G4Material("YSO",2.7*g/cm3, 3); + /*fYSO = new G4Material("YSO",4.5*g/cm3, 3); //Originally listed as 2.7 fYSO->AddElement(fY,2); fYSO->AddElement(fO,5); fYSO->AddElement(fSi,1); - materialList["yso"] = fYSO; + materialList["yso"] = fYSO;*/ ///////////////////////////////////////////////////////////////// // Teflon (C2F4)n @@ -603,6 +605,8 @@ void nDetMaterials::defineScintillators(){ delete fEJ276; delete fEJ200MPT; delete fEJ276MPT; + delete fYSO; + delete fYSOMPT; } ///////////////////////////////////////////////////////////////// @@ -721,10 +725,71 @@ 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_EJ200, 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 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, electronYield_YSO, 36)->SetSpline(true); + fYSOMPT->AddProperty("PROTONSCINTILLATIONYIELD", particleEnergy, protonYield_YSO, 36)->SetSpline(true); + fYSOMPT->AddProperty("IONSCINTILLATIONYIELD", particleEnergy, ionYield_YSO, 36)->SetSpline(true); + + fYSO->SetMaterialPropertiesTable(fYSOMPT); // Update the material dictionary materialList["ej200"] = fEJ200; materialList["ej276"] = fEJ276; + materialList["yso"] = fYSO; scintsAreDefined = true; } From ce0e895c8824de3fac30d0541c5dccf821ce7ae3 Mon Sep 17 00:00:00 2001 From: icox2 Date: Wed, 1 Jul 2020 15:15:58 -0400 Subject: [PATCH 03/17] Fixed implant diffuser, etc. --- include/nDetConstruction.hh | 2 +- source/nDetConstruction.cc | 18 +++++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/include/nDetConstruction.hh b/include/nDetConstruction.hh index 0bb7c36..54e4436 100644 --- a/include/nDetConstruction.hh +++ b/include/nDetConstruction.hh @@ -113,7 +113,7 @@ class nDetConstruction : public G4VUserDetectorConstruction{ /** Return a pointer to the PMT response for the left PMT */ - //pmtResponse *GetPmtResponse(){ return center[0].getPmtResponse(); } //This is for the implant detector + pmtResponse *GetPmtResponse(){ return center[0].getPmtResponse(); } //This is for the implant detector /** Get a copy of the current vector of detectors */ diff --git a/source/nDetConstruction.cc b/source/nDetConstruction.cc index a0ccd7e..bfc938f 100644 --- a/source/nDetConstruction.cc +++ b/source/nDetConstruction.cc @@ -102,9 +102,7 @@ G4VPhysicalVolume* nDetConstruction::ConstructImplant(){ currentImplant = imp; // Build the detector - //det->construct(); imp->construct(); - // Place the detector into the world. imp->placeImplant(expHall->getLogicalVolume()); } @@ -274,13 +272,15 @@ bool nDetConstruction::AddImplantGeometry(const G4String &geom){ // Segment the PMT photo-sensitive surface if(params.PmtIsSegmented()){ setSegmentedPmt(); - if(!gainMatrixFilename.empty()) + if(!gainMatrixFilename.empty()){ loadPmtGainMatrix(); + } } // Load the anode quantum efficiency - if(!spectralResponseFilename.empty()) + if(!spectralResponseFilename.empty()){ loadPmtSpectralResponse(); + } // Copy the center-of-mass calculators to the new detector centerOfMass *cmI = currentImplant->getCenterOfMass(); @@ -331,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; } @@ -343,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"); } @@ -350,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"); } @@ -357,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"); } @@ -364,6 +370,8 @@ 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"); } From 6ea9ac12ea5fe9d65efe23c2f99c39c4e8439476 Mon Sep 17 00:00:00 2001 From: icox2 Date: Tue, 28 Jul 2020 09:07:21 -0400 Subject: [PATCH 04/17] Working reconCom image, begin particle source --- dict/def.struct | 1 - gain/distortionTest.dat | 8 ---- include/G4Particle.hh | 26 ++++++++++++ include/centerOfMass.hh | 2 +- include/nDetParticleSource.hh | 10 +++++ include/nDetRunAction.hh | 2 + mac/pspmt.mac | 28 ++++++++----- source/G4Particle.cc | 58 +++++++++++++++++++++++++++ source/centerOfMass.cc | 12 +++--- source/nDetMaterials.cc | 2 +- source/nDetParticleSource.cc | 32 +++++++++++++-- source/nDetParticleSourceMessenger.cc | 7 ++++ source/nDetRunAction.cc | 46 +++++++++++---------- 13 files changed, 182 insertions(+), 52 deletions(-) delete mode 100644 gain/distortionTest.dat create mode 100644 include/G4Particle.hh create mode 100644 source/G4Particle.cc diff --git a/dict/def.struct b/dict/def.struct index 846d27d..de1b0c6 100644 --- a/dict/def.struct +++ b/dict/def.struct @@ -78,7 +78,6 @@ double reconComX Left and right PMT photon center-of-mass along the X-axis compu 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_TYPES END_CLASS ##################################################################### diff --git a/gain/distortionTest.dat b/gain/distortionTest.dat deleted file mode 100644 index cbdc19c..0000000 --- a/gain/distortionTest.dat +++ /dev/null @@ -1,8 +0,0 @@ -78 80 85 88 89 81 89 96 -77 50 50 95 96 93 91 98 -77 50 50 91 92 83 84 96 -78 69 82 95 97 86 83 94 -78 70 80 92 97 84 83 95 -75 71 79 89 99 85 81 95 -70 77 81 87 100 92 96 93 -72 73 74 80 90 93 99 92 diff --git a/include/G4Particle.hh b/include/G4Particle.hh new file mode 100644 index 0000000..5b77747 --- /dev/null +++ b/include/G4Particle.hh @@ -0,0 +1,26 @@ +//This file uses the G4Alpha.hh template for any ion to be include and used for implantation +#ifndef G4Particle_h +#define G4Particle_h 1 + +#include "globals.hh" +#include "G4ios.hh" +#include "G4ParticleDefinition.hh" +#include "G4Ions.hh" + +// ###################################################################### +// ### PARTICLE ### +// ###################################################################### + +class G4Particle : public G4Ions + { + private: + static G4Particle* theInstance; + G4Particle(){} + ~G4Particle(){} + public: + static G4Particle* Definition(); + static G4Particle* ParticleDefinition(); + static G4Particle* Particle(); + }; + +#endif diff --git a/include/centerOfMass.hh b/include/centerOfMass.hh index e275d0c..56f97f3 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 diff --git a/include/nDetParticleSource.hh b/include/nDetParticleSource.hh index 06daa85..533bcb5 100644 --- a/include/nDetParticleSource.hh +++ b/include/nDetParticleSource.hh @@ -196,6 +196,16 @@ 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 G4String &str); + /** Set a beam of mono-energetic gamma-rays * @param energy_ Energy of the beam (in MeV) */ diff --git a/include/nDetRunAction.hh b/include/nDetRunAction.hh index 8113944..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; @@ -264,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 diff --git a/mac/pspmt.mac b/mac/pspmt.mac index a265405..3e5dca4 100644 --- a/mac/pspmt.mac +++ b/mac/pspmt.mac @@ -18,9 +18,9 @@ # Mylar and optical grease thickness. /nDet/implant/setMylarThickness 0.025 -/nDet/implant/setGreaseThickness 0.1 +/nDet/implant/setGreaseThickness 1.0 -# Light diffuser. +# Light /nDet/implant/setDiffuserLength 1.5 # Choose Scintillator @@ -35,9 +35,10 @@ ################## # NEXT 2x2x10 in^3 -/nDet/implant/setDetectorLength 5.0 +/nDet/implant/setDetectorLength 1.5 /nDet/implant/setDetectorWidth 5.08 /nDet/implant/setDetectorThickness 50.8 +/nDet/implant/setWindowThickness 1. /nDet/implant/setNumColumns 20 /nDet/implant/setNumRows 20 /nDet/implant/setStart 1 @@ -52,20 +53,25 @@ # 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 distortionTest1.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/setCylindrical 100 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 + # Update the detector. /nDet/implant/update -# Load PSPMT gain matrix -# NOTE: This MUST be done AFTER calling '/nDet/implant/update' otherwise it will fail -/nDet/implant/setGainMatrix gains/distortionTest.dat - -# Load PSPMT spectral response function -/nDet/implant/setSpectralResponse spectral/hamamatsuH12700A.root ################ # OUTPUT SETUP # @@ -106,7 +112,7 @@ # Available source types: 137Cs 60Co 133Ba 241Am 90Sr 252Cf #/nDet/source/type 252Cf -/nDet/source/type gamma 1.0 +/nDet/source/type 137Cs #/nDet/source/beam gamma 0.25 #/nDet/source/beam 137Cs #/nDet/source/beam gamma 0.03 @@ -128,4 +134,4 @@ # RUN CONTROL # ############### -/run/beamOn 1000 +/run/beamOn 1000000 diff --git a/source/G4Particle.cc b/source/G4Particle.cc new file mode 100644 index 0000000..66c8887 --- /dev/null +++ b/source/G4Particle.cc @@ -0,0 +1,58 @@ +//This file is based off of G4Alpha.cc for creating any particle for implantation +#include "G4Particle.hh" +#include "G4SystemOfUnits.hh" +#include "G4ParticleTable.hh" + +// ###################################################################### +// ### PARTICLE ### +// ###################################################################### + +G4Particle* G4Particle::theInstance = 0; + +G4Particle* G4Particle::Definition(){ + if (theInstance !=0) return theInstance; + const G4String name = "particle"; + // search in particle table] + G4ParticleTable* pTable = G4ParticleTable::GetParticleTable(); + G4Ions* anInstance = reinterpret_cast(pTable->FindParticle(name)); + if (anInstance ==0) + { + // create particle + // + // Arguments for constructor are as follows + // name mass width charge + // 2*spin parity C-conjugation + // 2*Isospin 2*Isospin3 G-parity + // type lepton number baryon number PDG encoding + // stable lifetime decay table + // shortlived subType anti_encoding + // excitation + anInstance = new G4Ions( + name, 3.727379*GeV, 0.0*MeV, +2.0*eplus, + 0, +1, 0, + 0, 0, 0, + "nucleus", 0, +4, 1000020040, + true, -1.0, NULL, + false, "static", -1000020040, + 0.0 + ); + + } + + theInstance = reinterpret_cast(anInstance); + return theInstance; + } + + G4Particle* G4Particle::AlphaDefinition() +{ + return Definition(); + } + + G4Particle* G4Particle::Alpha() +{ + if (theInstance !=0) return theInstance + + return Definition(); +} + + diff --git a/source/centerOfMass.cc b/source/centerOfMass.cc index 206212a..7da8683 100644 --- a/source/centerOfMass.cc +++ b/source/centerOfMass.cc @@ -124,10 +124,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"<AddProperty("RINDEX", photonEnergy_YSO_2, RefIndex_YSO, 2); - fYSOMPT->AddProperty("ABSLENGTH", photonEnergy_YSO_2, Absorption_EJ200, 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 diff --git a/source/nDetParticleSource.cc b/source/nDetParticleSource.cc index 772b1eb..ec49a4f 100644 --- a/source/nDetParticleSource.cc +++ b/source/nDetParticleSource.cc @@ -17,6 +17,8 @@ #include "G4SystemOfUnits.hh" #include "G4Neutron.hh" #include "G4Gamma.hh" +#include "G4Alpha.hh" +#include "G4Ions.hh" #include "G4OpticalPhoton.hh" #include "G4Electron.hh" #include "Randomize.hh" @@ -43,7 +45,6 @@ nDetParticleSource::nDetParticleSource(nDetDetector *det/*=NULL*/, nDetImplant * 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") { - std::cout<<"In Particle Source"<SetDetector(det); - std::cout<<"In Detector Source"<SetImplant(imp); - std::cout<<"In Implant Source"<SetParticleDefinition(G4Alpha::AlphaDefinition()); + SetBeamEnergy(energy_*MeV); +} + +void nDetParticleSource::SetIonBeam(const G4String &str){ + // Expects a space-delimited string of the form: + // " [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 " << typeName << " Ion source.\n"; + Reset(); + //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 747f10c..0dbaa11 100644 --- a/source/nDetParticleSourceMessenger.cc +++ b/source/nDetParticleSourceMessenger.cc @@ -65,6 +65,10 @@ 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 G4UIcmdWithAString("/nDet/source/ion", this)); // type of source (252Cf, 137Cs, etc) + addGuidance("Set a pre-defined isotropic ion particle source"); + addGuidance("100Sn for Tin-100 beam for implantation"); } void nDetParticleSourceMessenger::SetNewChildValue(G4UIcommand* command, G4String newValue){ @@ -119,6 +123,9 @@ void nDetParticleSourceMessenger::SetNewChildValue(G4UIcommand* command, G4Strin else if(index == 15){ fAction->SetBeamEnergySigma(newValue); } + else if(index==16){ + //fAction-> + } } /*void nDetImplantParticleSourceMessenger::addAllCommands(){ diff --git a/source/nDetRunAction.cc b/source/nDetRunAction.cc index 84eaedf..a1c1112 100644 --- a/source/nDetRunAction.cc +++ b/source/nDetRunAction.cc @@ -13,6 +13,7 @@ #include "nDetSteppingAction.hh" #include "nDetParticleSource.hh" #include "nDetMasterOutputFile.hh" +#include "nDetDetector.hh" #include "termColors.hh" const double KINETIC_ENERGY_THRESHOLD = 0.03; // MeV @@ -452,8 +453,11 @@ bool nDetRunAction::processImplant(nDetImplant* imp){ double targetTimeOffset = source->GetTargetTimeOffset(); bool Ftrigger = false; // Get pointers to the CoM calculators + params = detector->GetDetectorParameters(); centerOfMass *cmI = imp->getCenterOfMass(); - + cmI->setSegmentedPmt(¶ms); + cmI->loadGainMatrix("distortionTest1.dat"); + debugData.nPhotons[0] += cmI->getNumDetected(); // Compute the total number of detected photons @@ -474,7 +478,7 @@ bool nDetRunAction::processImplant(nDetImplant* imp){ G4ThreeVector centerI = cmI->getCenter(); debugData.photonDetComX[0] = centerI.getX(); debugData.photonDetComY[0] = centerI.getY(); - //debugData.photonDetComZ[0] = centerL.getZ(); debugData.photonDetComZ[1] = centerR.getZ(); + //debugData.photonDetComZ[0] = centerI.getZ(); // Get photon arrival times at the PMTs debugData.photonMinTime[0] = cmI->getMinArrivalTime(); @@ -535,25 +539,24 @@ bool nDetRunAction::processImplant(nDetImplant* imp){ } // Get the digitizer response of the anodes. - /*pmtResponse *anodeResponseL = cmL->getAnodeResponse(); - pmtResponse *anodeResponseR = cmR->getAnodeResponse(); + pmtResponse *anodeResponseI = cmI->getAnodeResponse(); // Digitize anode waveforms and integrate. - float anodeQDC[2][4]; + double anodeQDC[4]={0}; for(size_t i = 0; i < 4; i++){ - anodeResponseL[i].digitize(); - anodeResponseR[i].digitize(); - debugData.anodeQDC[0][i] = anodeResponseL[i].integratePulseFromMaximum(); - debugData.anodeQDC[1][i] = anodeResponseR[i].integratePulseFromMaximum(); + anodeResponseI[i].digitize(); + debugData.anodeQDC[0][i] = anodeResponseI[i].integratePulseFromMaximum(); + anodeQDC[i] = debugData.anodeQDC[0][i]; } // Compute the anode positions. - for(size_t i = 0; i < 2; i++){ - debugData.reconDetComX[i] = -((anodeQDC[i][0]+anodeQDC[i][1])-(anodeQDC[i][2]+anodeQDC[i][3]))/(anodeQDC[i][0]+anodeQDC[i][1]+anodeQDC[i][2]+anodeQDC[i][3]); - debugData.reconDetComY[i] = ((anodeQDC[i][1]+anodeQDC[i][2])-(anodeQDC[i][3]+anodeQDC[i][0]))/(anodeQDC[i][0]+anodeQDC[i][1]+anodeQDC[i][2]+anodeQDC[i][3]); - } - outImplantData.reconComX = (debugData.reconDetComX[0] + debugData.reconDetComX[1]) / 2; - outImplantData.reconComY = (debugData.reconDetComY[0] + debugData.reconDetComY[1]) / 2;*/ + //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]); + debugData.reconDetComX[0] = cmI->getReconstructedX(); + debugData.reconDetComY[0] = cmI->getReconstructedY(); + //std::cout<<"recon "<getCenterSegment(debugData.centerOfMassColumn[0], debugData.centerOfMassRow[0]); @@ -679,7 +682,7 @@ 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++); } } @@ -785,8 +788,9 @@ bool nDetRunAction::AddDetectedPhoton(const G4Step *step, const double &mass/*=1 return true; } else if(isImplant){ - if(hitDetPmtI->addPoint(energy, time, position, mass)) + if(hitDetPmtI->addPoint(energy, time, position, mass)){ return true; + } } else{ if(hitDetPmtR->addPoint(energy, time, position, mass)) From d38de458422ef0456e9174ba215109b73b293186 Mon Sep 17 00:00:00 2001 From: icox2 Date: Tue, 28 Jul 2020 09:13:20 -0400 Subject: [PATCH 05/17] correct gain matrix --- source/nDetRunAction.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/nDetRunAction.cc b/source/nDetRunAction.cc index a1c1112..6e177ce 100644 --- a/source/nDetRunAction.cc +++ b/source/nDetRunAction.cc @@ -456,7 +456,7 @@ bool nDetRunAction::processImplant(nDetImplant* imp){ params = detector->GetDetectorParameters(); centerOfMass *cmI = imp->getCenterOfMass(); cmI->setSegmentedPmt(¶ms); - cmI->loadGainMatrix("distortionTest1.dat"); + cmI->loadGainMatrix("hamamatsuH12700A_LA0967.dat"); debugData.nPhotons[0] += cmI->getNumDetected(); From 1dde857c5e486db7e350bd5aa97ac0fc92918e8f Mon Sep 17 00:00:00 2001 From: icox2 Date: Tue, 28 Jul 2020 09:50:37 -0400 Subject: [PATCH 06/17] removed total current --- source/centerOfMass.cc | 4 +--- source/nextSim.cc | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/source/centerOfMass.cc b/source/centerOfMass.cc index 7da8683..499b8d5 100644 --- a/source/centerOfMass.cc +++ b/source/centerOfMass.cc @@ -202,15 +202,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])); } } diff --git a/source/nextSim.cc b/source/nextSim.cc index e0307ab..89df7cf 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); From 6fe6f7f153ef3245e2c4f76cc75adc54e72697fb Mon Sep 17 00:00:00 2001 From: icox2 Date: Mon, 27 Dec 2021 16:47:12 -0500 Subject: [PATCH 07/17] initial workings on segmented light guide with messenger usage but no testing --- CMakeLists.txt | 6 +- include/G4Particle.hh | 26 ----- include/nDetConstruction.hh | 2 + include/nDetDetector.hh | 95 +++++++++++++++++ include/nDetDetectorLayer.hh | 24 ++++- include/nDetMaterials.hh | 44 ++++---- include/nDetParticleSource.hh | 3 +- mac/next.mac | 2 +- mac/pspmt.mac | 11 +- source/CMakeLists.txt | 2 +- source/G4Particle.cc | 58 ---------- source/nDetConstruction.cc | 7 ++ source/nDetConstructionMessenger.cc | 9 ++ source/nDetDetector.cc | 92 ++++++++++++++-- source/nDetDetectorLayer.cc | 40 +++++++ source/nDetDetectorMessenger.cc | 56 ++++++++++ source/nDetMaterials.cc | 147 +++++++++++++++++++++++++- source/nDetParticleSource.cc | 24 ++++- source/nDetParticleSourceMessenger.cc | 117 +------------------- source/nDetRunAction.cc | 8 +- source/nextSim.cc | 1 + 21 files changed, 528 insertions(+), 246 deletions(-) delete mode 100644 include/G4Particle.hh delete mode 100644 source/G4Particle.cc 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/include/G4Particle.hh b/include/G4Particle.hh deleted file mode 100644 index 5b77747..0000000 --- a/include/G4Particle.hh +++ /dev/null @@ -1,26 +0,0 @@ -//This file uses the G4Alpha.hh template for any ion to be include and used for implantation -#ifndef G4Particle_h -#define G4Particle_h 1 - -#include "globals.hh" -#include "G4ios.hh" -#include "G4ParticleDefinition.hh" -#include "G4Ions.hh" - -// ###################################################################### -// ### PARTICLE ### -// ###################################################################### - -class G4Particle : public G4Ions - { - private: - static G4Particle* theInstance; - G4Particle(){} - ~G4Particle(){} - public: - static G4Particle* Definition(); - static G4Particle* ParticleDefinition(); - static G4Particle* Particle(); - }; - -#endif diff --git a/include/nDetConstruction.hh b/include/nDetConstruction.hh index 54e4436..fbee71e 100644 --- a/include/nDetConstruction.hh +++ b/include/nDetConstruction.hh @@ -166,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:
diff --git a/include/nDetDetector.hh b/include/nDetDetector.hh index be040f3..7479b2c 100644 --- a/include/nDetDetector.hh +++ b/include/nDetDetector.hh @@ -3,6 +3,7 @@ #include "globals.hh" #include "G4RotationMatrix.hh" +#include "G4VPVParameterisation.hh" #include "gdmlSolid.hh" #include "centerOfMass.hh" @@ -261,6 +262,17 @@ 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;} + + protected: G4double pmtWidth; ///< The width (x-axis) of the PMT (in mm) G4double pmtHeight; ///< The height (y-axis) of the PMT (in mm) @@ -313,6 +325,19 @@ protected: 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,6 +728,12 @@ 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 @@ -873,6 +904,11 @@ public: */ 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 @@ -1000,6 +1036,8 @@ public: */ 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: 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 @@ -1011,6 +1049,19 @@ protected: 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 + + ////// + //These variables are for a segmented light guide + ////// + /*G4int fXseg; + G4int fYseg; + G4double fspacing; + G4double ftopWidth; + G4double ftopThick; + G4double fbotWidth; + G4double fbotThick; + G4double fzThick; + G4String fSegMaterial;*/ bool checkOverlaps; ///< Flag indicating that Geant should check for overlaps between all placed objects @@ -1072,6 +1123,50 @@ protected: * @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); + }; +/** @class LightGuideParameterisation + * @brief Used to construct a segmented and tapered light guide + * @author Ian Cox (icox2@vols.utk.edu) + * @date December 22, 2021 + */ + +class LightGuideParameterisation: public G4VPVParameterisation{ + public: + LightGuideParameterisation(G4int Xseg, G4int Yseg, G4double spacing, G4double topWidth, G4double topThick, G4double botWidth, G4double botThick, G4double zThick); + ~LightGuideParameterisation(); + + void ComputeTransformation (const G4int copyNo, G4VPhysicalVolume* physVol) const; + void ComputeDimensions (G4Trap& segment, const G4int copyNo, const G4VPhysicalVolume* physVol) const override; + + private: + G4int m_Xseg; + G4int m_Yseg; + G4double m_spacing; + G4double m_xStart; + G4double m_yStart; + G4double m_zStart; + G4double m_topWidth; + G4double m_topThick; + G4double m_botWidth; + G4double m_botThick; + G4double m_zThick; +}; + + class ChamberParameterisation: public G4VPVParameterisation{ + public: + ChamberParameterisation(G4int NoChambers, G4double startZ, G4double spacing, G4double widthChamber,G4double lenInitial,G4double lenFinal); + ~ChamberParameterisation(); + void ComputeTransformation (const G4int copyNo, G4VPhysicalVolume* physVol) const; + void ComputeDimensions (G4Box& trackerLayer, const G4int copyNo, const G4VPhysicalVolume* physVol) const; + + private: + G4double fStartZ; + G4double fspacing; + G4double fHalfLengthFirst; + G4double fHalfLengthIncr; + G4double fHalfWidth; + }; + #endif diff --git a/include/nDetDetectorLayer.hh b/include/nDetDetectorLayer.hh index 97164ee..d0acc4c 100644 --- a/include/nDetDetectorLayer.hh +++ b/include/nDetDetectorLayer.hh @@ -123,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] @@ -161,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) diff --git a/include/nDetMaterials.hh b/include/nDetMaterials.hh index 61ce458..e8f0ae1 100644 --- a/include/nDetMaterials.hh +++ b/include/nDetMaterials.hh @@ -32,7 +32,9 @@ class nDetMaterials{ G4Element* fF; ///< Flourine G4Element* fSi; ///< Silicon G4Element* fAl; ///< Aluminium - G4Element* fY; ///< Yttrium + G4Element* fY; ///< Yttrium + G4Element* fLa; ///< Lanthinum + G4Element* fBr; ///< Bromine G4Material* fAir; ///< Material corresponding to air G4Material* fVacuum; ///< Material corresponding to natural vacuum @@ -44,8 +46,10 @@ 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* fYSO; ///< Material corresponding to yttrium + G4Material* fAluminum; ///< Material corresponding to aluminum + G4Material* fYSO; ///< Material corresponding to yttrium orthosilicate + G4Material* fYAP; ///< yttrium aluminum perovskite + G4Material* fLaBr3; ///< Lanthinum Bromide // Material table properties @@ -53,31 +57,33 @@ class nDetMaterials{ 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* fYSOMPT; ///< Material properties table for YSO scintillator + G4MaterialPropertiesTable* fYAPMPT; ///< MPT for YAP 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 + + // 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 533bcb5..df5219f 100644 --- a/include/nDetParticleSource.hh +++ b/include/nDetParticleSource.hh @@ -204,7 +204,8 @@ class nDetParticleSource : public G4GeneralParticleSource { /** Set a beam of mono-energetic ions * @param energy_ Energy of the beam (in MeV) */ - void SetIonBeam(const G4String &str); + void SetIonBeam(const double &energy_); + //void SetIonBeam(const G4String &str); /** Set a beam of mono-energetic gamma-rays * @param energy_ Energy of the beam (in MeV) diff --git a/mac/next.mac b/mac/next.mac index 5959729..ba567a8 100644 --- a/mac/next.mac +++ b/mac/next.mac @@ -123,4 +123,4 @@ # RUN CONTROL # ############### -#/run/beamOn 100 +/run/beamOn 10 diff --git a/mac/pspmt.mac b/mac/pspmt.mac index 3e5dca4..7fca48d 100644 --- a/mac/pspmt.mac +++ b/mac/pspmt.mac @@ -56,13 +56,12 @@ # 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 distortionTest1.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/setCylindrical 100 0 0 +/nDet/implant/setCylindrical 0.5 0 0 /nDet/implant/setRotation 0 270 0 /nDet/implant/addGeometry module @@ -78,7 +77,7 @@ ################ # Set the output filename prefix -/nDet/output/filename distortion_test_1m.root +/nDet/output/filename test_1m.root /nDet/output/title PSPMT, 0.5 MeV, 1 m from detector #/nDet/output/index 69 #/nDet/output/overwrite true @@ -112,7 +111,7 @@ # Available source types: 137Cs 60Co 133Ba 241Am 90Sr 252Cf #/nDet/source/type 252Cf -/nDet/source/type 137Cs +/nDet/source/type alpha 10 #/nDet/source/beam gamma 0.25 #/nDet/source/beam 137Cs #/nDet/source/beam gamma 0.03 @@ -134,4 +133,4 @@ # RUN CONTROL # ############### -/run/beamOn 1000000 +#/run/beamOn 1000 diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 837484c..c085c03 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -32,7 +32,7 @@ set(NextSimDetectorSources nDetMaterials.cc nDetMaterialsMessenger.cc nDetConstr Polyhedron.cc IS530_Chamber.cc IS530_Plastic.cc Tape.cc CloverQuadBuchDetector.cc CloverQuadDetector.cc CloverSingleBuchDetector.cc CloverSingleDetector.cc ) -set(NextSimGeneratorSources nDetParticleSource.cc nDetParticleSourceMessenger.cc) +set(NextSimGeneratorSources nDetParticleSource.cc nDetParticleSourceMessenger.cc G4Implant.cc) set(NextSimPeripheralSources optionHandler.cc termColors.cc) #Add the sources to the library. diff --git a/source/G4Particle.cc b/source/G4Particle.cc deleted file mode 100644 index 66c8887..0000000 --- a/source/G4Particle.cc +++ /dev/null @@ -1,58 +0,0 @@ -//This file is based off of G4Alpha.cc for creating any particle for implantation -#include "G4Particle.hh" -#include "G4SystemOfUnits.hh" -#include "G4ParticleTable.hh" - -// ###################################################################### -// ### PARTICLE ### -// ###################################################################### - -G4Particle* G4Particle::theInstance = 0; - -G4Particle* G4Particle::Definition(){ - if (theInstance !=0) return theInstance; - const G4String name = "particle"; - // search in particle table] - G4ParticleTable* pTable = G4ParticleTable::GetParticleTable(); - G4Ions* anInstance = reinterpret_cast(pTable->FindParticle(name)); - if (anInstance ==0) - { - // create particle - // - // Arguments for constructor are as follows - // name mass width charge - // 2*spin parity C-conjugation - // 2*Isospin 2*Isospin3 G-parity - // type lepton number baryon number PDG encoding - // stable lifetime decay table - // shortlived subType anti_encoding - // excitation - anInstance = new G4Ions( - name, 3.727379*GeV, 0.0*MeV, +2.0*eplus, - 0, +1, 0, - 0, 0, 0, - "nucleus", 0, +4, 1000020040, - true, -1.0, NULL, - false, "static", -1000020040, - 0.0 - ); - - } - - theInstance = reinterpret_cast(anInstance); - return theInstance; - } - - G4Particle* G4Particle::AlphaDefinition() -{ - return Definition(); - } - - G4Particle* G4Particle::Alpha() -{ - if (theInstance !=0) return theInstance - - return Definition(); -} - - diff --git a/source/nDetConstruction.cc b/source/nDetConstruction.cc index bfc938f..07cc7d3 100644 --- a/source/nDetConstruction.cc +++ b/source/nDetConstruction.cc @@ -376,6 +376,13 @@ void nDetConstruction::AddLightGuide(const G4String &input){ 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" diff --git a/source/nDetConstructionMessenger.cc b/source/nDetConstructionMessenger.cc index 314691b..a97369b 100644 --- a/source/nDetConstructionMessenger.cc +++ b/source/nDetConstructionMessenger.cc @@ -13,6 +13,7 @@ #include "G4UIcmdWithADouble.hh" #include "G4UIcmdWithAnInteger.hh" #include "G4UIcmdWithoutParameter.hh" +#include "G4UIcmdWithABool.hh" #include "G4SystemOfUnits.hh" void nDetConstructionMessenger::addAllCommands(){ @@ -155,6 +156,9 @@ void nDetConstructionMessenger::addAllCommands(){ addCommand(new G4UIcmdWithoutParameter("/nDet/implant/printAll", this)); addGuidance("Print construction parameters for all defined implants"); + addCommand(new G4UIcmdWithABool("/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> "); + } void nDetConstructionMessenger::SetNewChildValue(G4UIcommand* command, G4String newValue){ @@ -323,5 +327,10 @@ void nDetConstructionMessenger::SetNewChildValue(G4UIcommand* command, G4String else if(index == 27){ fDetector->PrintAllDetectors(); } + + //LightGuideParameterisation commands + else if(index == 28 && newValue){ + fDetector->AddSegmentedLightGuide(newValue); + } } } diff --git a/source/nDetDetector.cc b/source/nDetDetector.cc index a6ff24a..ccdb972 100644 --- a/source/nDetDetector.cc +++ b/source/nDetDetector.cc @@ -7,12 +7,14 @@ #include "G4SubtractionSolid.hh" #include "G4UnionSolid.hh" #include "G4LogicalSkinSurface.hh" +#include "G4PVParameterised.hh" #include "G4Tubs.hh" #include "G4Box.hh" #include "G4Trd.hh" #include "G4Cons.hh" #include "G4Sphere.hh" +#include "G4Trap.hh" #include "nDetDetector.hh" #include "nDetDetectorLayer.hh" @@ -160,10 +162,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; @@ -582,13 +584,14 @@ void nDetDetector::loadLightGuide(gdmlSolid *solid, const G4ThreeVector &rotatio /////////////////////////////////////////////////////////////////////////////// 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(false) + assembly_logV(NULL), assembly_physV(NULL), + layerSizeX(0), layerSizeY(0), offsetZ(0), + parentCopyNum(0), firstSegmentCopyNum(0), lastSegmentCopyNum(0), + checkOverlaps(false) { copyCenterOfMass(*detector->GetCenterOfMass()); //This has been adjusted materials = matptr; + //std::cout<<"!! Implant !! "<GetDetectorParameters().GetNumPmtColumns()<fAcrylic; + auto seg_solid = new G4Trap("trap"); + //auto seg_solid = new G4Box("seg_solid",2*mm,2*mm,10*mm); + auto seg_log = new G4LogicalVolume(seg_solid,lg_mat,"seg_log"); + G4VPVParameterisation* lightGuideParam = new LightGuideParameterisation(Xseg,Yseg,spacing,topWidth,topThick,botWidth,botThick,zThick); + G4VPhysicalVolume* lightGuide = new G4PVParameterised("lg_para",seg_log,assembly_logV,kXAxis,numSegs,lightGuideParam); + return; +} + void nDetImplant::loadGDML(gdmlSolid *solid){ if(!solid || !solid->isLoaded()) return; @@ -994,3 +1012,61 @@ void nDetImplant::loadLightGuide(gdmlSolid *solid, const G4ThreeVector &rotation offsetZ += solid->getLength(); fTrapezoidLength = solid->getLength()*mm; } + +LightGuideParameterisation::LightGuideParameterisation(G4int Xseg, G4int Yseg, G4double spacing, G4double topWidth, G4double topThick, G4double botWidth, G4double botThick, G4double zThick): + G4VPVParameterisation(), + m_Xseg(Xseg), + m_Yseg(Yseg), + m_spacing(spacing), + m_xStart(double(Xseg)*botWidth/2.+spacing*(Xseg/2)), + m_yStart(double(Yseg)*botThick/2.+spacing*(Yseg/2)), + m_zStart(0.), + m_topWidth(topWidth), + m_topThick(topThick), + m_botWidth(botWidth), + m_botThick(botThick), + m_zThick(zThick) + { + G4cout<<"Building Light Guide Parametrisation"<SetTranslation(origin); + physVol->SetRotation(0); +} + +void LightGuideParameterisation::ComputeDimensions(G4Trap& segment, const G4int copyNo, const G4VPhysicalVolume* physVol) const{ + G4double xposb = (copyNo%m_Xseg-m_Xseg)*(m_botWidth); + G4double yposb = (copyNo/m_Yseg-m_Yseg)*(m_botThick); + G4double xpost = (copyNo%m_Xseg-m_Xseg)*(m_topWidth); + G4double ypost = (copyNo/m_Yseg-m_Yseg)*(m_topThick); + G4double zpos = 0.; + G4double pTheta; + if(xposb<0) + pTheta = -1*atan((sqrt(pow(xpost,2)+pow(ypost,2))-sqrt(pow(xposb,2)+pow(yposb,2)))/(m_zThick)); + else + pTheta = atan((sqrt(pow(xpost,2)+pow(ypost,2))-sqrt(pow(xposb,2)+pow(yposb,2)))/(m_zThick)); + G4double pPhi = atan((ypost-yposb+0.0000001)/(xpost-xposb)); + segment.SetAllParameters( + m_zThick/2., // pDz Half z length + pTheta, //pTheta Polar angle of the line joining the centers of the faces at -/+ pDz + pPhi, //pPhi Azimuthal angle of the line joining the center of the face at -pDz to the center of the face at +pDz + m_botThick/2., //pDy1 Half y length at -pDz + m_botWidth/2., //pDx1 Half x length of the side at y=-pDy1 of the face at -pDz + m_botWidth/2., //pDx2 Half x length of the side at y=+pDy1 of the face at -pDz + 0*degree, //pAlp1 Angle with respect to the y-axis from the center of the side (lower endcap) + m_topThick/2., //pDy2 Half y length at +pDz + m_topWidth/2., //pDx3 Half x length of the side at y=-pDy2 of the face at -pDz + m_topWidth/2., //pDx4 Half x length of the side at y=+pDy2 of the face at -pDz + 0*degree //pAlp2 Angle with respect to the y-axis from the center of the side (upper endcap) + ); +} \ No newline at end of file diff --git a/source/nDetDetectorLayer.cc b/source/nDetDetectorLayer.cc index 238ef5a..afe0835 100644 --- a/source/nDetDetectorLayer.cc +++ b/source/nDetDetectorLayer.cc @@ -4,6 +4,7 @@ #include "nDetDetectorLayer.hh" #include "optionHandler.hh" // split_str + /////////////////////////////////////////////////////////////////////////////// // class greaseLayer /////////////////////////////////////////////////////////////////////////////// @@ -93,6 +94,45 @@ std::string lightGuideLayer::syntaxStr() const { return std::string("addLightGuide [material=G4_SILICON_DIOXIDE]"); } +/////////////////////////////////////////////////////////////////////////////// +// class segLightGuideLayer +/////////////////////////////////////////////////////////////////////////////// + +segLightGuideLayer::segLightGuideLayer(const +G4String &arg_) : nDetWorldObject(arg_,9), 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"<applySegmentedLightGuide(fXseg, fYseg, fspacing, ftopWidth, ftopThick, fbotWidth, fbotThick, fzThick); +} + +std::string segLightGuideLayer::syntaxStr() const{ + return std::string("<# x seg> <# y seg> "); +} + + /////////////////////////////////////////////////////////////////////////////// // class gdmlLightGuideLayer /////////////////////////////////////////////////////////////////////////////// diff --git a/source/nDetDetectorMessenger.cc b/source/nDetDetectorMessenger.cc index 8da87f1..72ea8a2 100644 --- a/source/nDetDetectorMessenger.cc +++ b/source/nDetDetectorMessenger.cc @@ -184,6 +184,34 @@ void nDetDetectorMessenger::addAllCommands(){ addCommand(new G4UIcmdWithADouble("/nDet/implant/setDetectorHeight", this)); addGuidance("Defines the height (Y) of the implant in cm"); + + + ///////////////////////////////////////////// + // 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"); } void nDetDetectorMessenger::SetNewChildValue(G4UIcommand* command, G4String newValue){ @@ -383,4 +411,32 @@ void nDetDetectorMessenger::SetNewChildValue(G4UIcommand* command, G4String newV G4double thickness = command->ConvertToDouble(newValue); fDetector->SetDetectorHeight(thickness*cm); } + else if(index == 52){ + G4double val = command->ConvertToDouble(newValue); + fDetector->setSegZThick(val); + } + else if(index == 53){ + G4double val = command->ConvertToDouble(newValue); + fDetector->setSegTopThick(val); + } + else if(index == 54){ + G4double val = command->ConvertToDouble(newValue); + fDetector->setSegTopWidth(val); + } + else if(index == 55){ + G4double val = command->ConvertToDouble(newValue); + fDetector->setSegBotThick(val); + } + else if(index == 56){ + G4double val = command->ConvertToDouble(newValue); + fDetector->setSegBotWidth(val); + } + else if(index == 57){ + G4int val = command->ConvertToInt(newValue); + fDetector->setSegX(val); + } + else if(index == 58){ + G4int val = command->ConvertToInt(newValue); + fDetector->setSegY(val); + } } diff --git a/source/nDetMaterials.cc b/source/nDetMaterials.cc index c253b5b..7ce44e2 100644 --- a/source/nDetMaterials.cc +++ b/source/nDetMaterials.cc @@ -48,6 +48,10 @@ nDetMaterials::~nDetMaterials(){ delete fEJ276MPT; delete fYSO; delete fYSOMPT; + delete fLaBr3; + delete fLaBr3MPT; + delete fYAP; + delete fYAPMPT; } delete messenger; } @@ -65,6 +69,8 @@ void nDetMaterials::initialize(){ elementList["Si"] = fSi; elementList["Al"] = fAl; elementList["Y"] = fY; + elementList["La"] = fLa; + elementList["Br"] = fBr; materialList["air"] = fAir; materialList["vacuum"] = fVacuum; @@ -73,6 +79,8 @@ void nDetMaterials::initialize(){ materialList["ej276"] = fEJ276; materialList["grease"] = fGrease; materialList["yso"] = fYSO; + materialList["labr3"] = fLaBr3; + materialList["yap"] = fYAP; materialList["quartz"] = fSiO2; materialList["silicon"] = fSilicon; materialList["mylar"] = fMylar; @@ -92,6 +100,8 @@ void nDetMaterials::initialize(){ visAttributesList["ej200"] = visScint; visAttributesList["ej276"] = visScint; visAttributesList["yso"] = visScint; + visAttributesList["labr3"] = visScint; + visAttributesList["yap"] = visScint; visAttributesList["grease"] = visGrease; visAttributesList["quartz"] = visWindow; visAttributesList["silicon"] = visSensitive; @@ -128,7 +138,7 @@ 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){ @@ -359,6 +369,8 @@ void nDetMaterials::defineMaterials(){ fSi = nist.searchForElement("Si"); fAl = nist.searchForElement("Al"); fY = nist.searchForElement("Y"); + fLa = nist.searchForElement("La"); + fBr = nist.searchForElement("Br"); // Air fAir = nist.searchForMaterial("G4_AIR"); @@ -607,6 +619,8 @@ void nDetMaterials::defineScintillators(){ delete fEJ276MPT; delete fYSO; delete fYSOMPT; + delete fLaBr3; + delete fLaBr3MPT; } ///////////////////////////////////////////////////////////////// @@ -786,10 +800,141 @@ void nDetMaterials::defineScintillators(){ 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.580, 1.580}; + G4double Absorption_LaBr3[2] = {400*cm, 400*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", 0.64*17400/MeV); // 64% of Anthracene + fLaBr3MPT->AddConstProperty("SCINTILLATIONYIELD", 10000/MeV); // Scintillation efficiency as per Eljen specs + 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 + ///////////////////////////////////////////////////////////////// + + 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_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_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_YAP2[2] = {16.8179*keV, 23.0707*keV}; + G4double RefIndex_YAP[2] = {1.80, 1.80}; //Data taken from https://www.advatech-uk.co.uk/yso_ce.html + G4double Absorption_YAP[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 + + fYAPMPT = new G4MaterialPropertiesTable(); + fYAPMPT->AddProperty("RINDEX", photonEnergy_YAP2, RefIndex_YSO, 2); + fYAPMPT->AddProperty("ABSLENGTH", photonEnergy_YAP2, Absorption_YSO, 2); + fYAPMPT->AddProperty("FASTCOMPONENT", photonEnergy_YAP, ScintilFast_YSO, 44); + + fYAPMPT->AddConstProperty("SCINTILLATIONYIELD", 24000/MeV); // Photon yield as found in paper above for 137Cs + 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 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_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_YSO, 36)->SetSpline(true); + fYAPMPT->AddProperty("PROTONSCINTILLATIONYIELD", particleEnergy, protonYield_YSO, 36)->SetSpline(true); + fYAPMPT->AddProperty("IONSCINTILLATIONYIELD", particleEnergy, ionYield_YSO, 36)->SetSpline(true); + + fYAP->SetMaterialPropertiesTable(fYAPMPT); + // Update the material dictionary materialList["ej200"] = fEJ200; materialList["ej276"] = fEJ276; materialList["yso"] = fYSO; + materialList["labr3"] = fLaBr3; + materialList["yap"] = fYAP; scintsAreDefined = true; } diff --git a/source/nDetParticleSource.cc b/source/nDetParticleSource.cc index ec49a4f..6132bd0 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" @@ -19,6 +18,7 @@ #include "G4Gamma.hh" #include "G4Alpha.hh" #include "G4Ions.hh" +#include "G4Implant.hh" #include "G4OpticalPhoton.hh" #include "G4Electron.hh" #include "Randomize.hh" @@ -153,6 +153,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); else if(typeName == "gamma") SetGammaRayBeam(beamEnergy); else if(typeName == "laser"){ @@ -308,18 +312,27 @@ 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 G4String &str){ +void nDetParticleSource::SetIonBeam(const double &energy_){ + std::cout<<"Ion Beam"<SetParticleDefinition(G4Implant::ImplantDefinition()); + SetBeamEnergy(energy_*MeV); +} + +/*void nDetParticleSource::SetIonBeam(const G4String &str){ // Expects a space-delimited string of the form: // " [energy(MeV)]" std::vector args; @@ -334,11 +347,12 @@ void nDetParticleSource::SetIonBeam(const G4String &str){ if(Nargs >= 2) beamEnergy = strtod(args.at(1).c_str(), NULL); - std::cout << " nDetParticleSource: Setting " << typeName << " Ion source.\n"; + std::cout << " nDetParticleSource: Setting " <SetParticleDefinition(G4Alpha::AlphaDefinition()); + //GetCurrentSource()->SetParticleDefinition(G4Implant::ImplantDefinition()); + GetCurrentSource()->SetParticleDefinition(G4Alpha::AlphaDefinition()); SetBeamEnergy(beamEnergy*MeV); -} +}*/ void nDetParticleSource::SetGammaRayBeam(const double &energy_){ Reset(); diff --git a/source/nDetParticleSourceMessenger.cc b/source/nDetParticleSourceMessenger.cc index 0dbaa11..257e7c1 100644 --- a/source/nDetParticleSourceMessenger.cc +++ b/source/nDetParticleSourceMessenger.cc @@ -68,7 +68,7 @@ void nDetParticleSourceMessenger::addAllCommands(){ addCommand(new G4UIcmdWithAString("/nDet/source/ion", this)); // type of source (252Cf, 137Cs, etc) addGuidance("Set a pre-defined isotropic ion particle source"); - addGuidance("100Sn for Tin-100 beam for implantation"); + addGuidance("108Xe for Xenon-108 beam for implantation"); } void nDetParticleSourceMessenger::SetNewChildValue(G4UIcommand* command, G4String newValue){ @@ -124,119 +124,6 @@ void nDetParticleSourceMessenger::SetNewChildValue(G4UIcommand* command, G4Strin fAction->SetBeamEnergySigma(newValue); } else if(index==16){ - //fAction-> + //fAction->SetIonBeam(newValue); } } - -/*void nDetImplantParticleSourceMessenger::addAllCommands(){ - addDirectory("/nDet/source/", "Particle Source Control"); - - G4UIcmdWithAnInteger *cmd = new G4UIcmdWithAnInteger("/nDet/source/sample", this); - cmd->SetParameterName("Nsamples", true); - cmd->SetGuidance("Test distribution by outputting a random energy"); - cmd->SetDefaultValue(1); - addCommand(cmd); // test function - - addCommand(new G4UIcmdWith3Vector("/nDet/source/direction", this)); // direction of source - addGuidance("Set the direction of the source by specifying angles about the x, y, and z axes (in deg)"); - - addCommand(new G4UIcmdWithAString("/nDet/source/type", this)); // type of source (252Cf, 137Cs, etc) - addGuidance("Set a pre-defined isotropic particle source"); - addGuidance("252Cf 137Cs 60Co 133Ba 241Am 90Sr neutron gamma electron laser"); - - addCommand(new G4UIcmdWithADouble("/nDet/source/spot", this)); // beamspot radius (mm) - addGuidance("Set the radius of the beam (in mm)"); - - addCommand(new G4UIcmdWithADouble("/nDet/source/spot0", this)); // beamspot radius (mm) - addGuidance("Set the secondary radius of the beam (in mm)"); - - addCommand(new G4UIcmdWithAString("/nDet/source/shape", this)); // beamspot shape type - addGuidance("Set the shape of the beamspot"); - addCandidates("point circle annulus ellipse square rectangle vertical horizontal gauss"); - - addCommand(new G4UIcmdWithAnInteger("/nDet/source/iso", this)); - addGuidance("Set the source isotropic mode (0=off, 1=psuedo, 2=realistic)"); - - addCommand(new G4UIcmdWith3Vector("/nDet/source/range", this)); - addGuidance("Set the energy range of a continuous distribution source"); - - addCommand(new G4UIcmdWithAString("/nDet/source/reaction", this)); - addGuidance("Load a reaction file. SYNTAX: reaction "); - - addCommand(new G4UIcmdWithAString("/nDet/source/edist", this)); - addGuidance("Read the source energy distribution from an ascii file. SYNTAX: edist "); - - addCommand(new G4UIcmdWithAString("/nDet/source/addLevel", this)); - addGuidance("Add a discrete energy level to the current source. SYNTAX: addLevel [intensity] [particle]"); - - addCommand(new G4UIcmdWithAString("/nDet/source/test", this)); - addGuidance("Simulate a specified number of events and write particle energies to an output file. SYNTAX: test "); - - addCommand(new G4UIcmdWithoutParameter("/nDet/source/reset", this)); - addGuidance("Reset the source and clear all defined energy levels"); - - addCommand(new G4UIcmdWithAString("/nDet/source/inter", this)); - addGuidance("Set the default interpolation method for user defined energy distributions"); - addCandidates("Lin Log Exp Spline"); - - addCommand(new G4UIcmdWithADouble("/nDet/source/setEnergy", this)); - addGuidance("Set the current energy level to mono-energetic and set the energy (in MeV)"); - - 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 "); -} - -void nDetImplantParticleSourceMessenger::SetNewChildValue(G4UIcommand* command, G4String newValue){ - size_t index; - if(!findCommand(command, newValue, index)) return; - if(index == 0){ - fActionI->Print(G4UIcommand::ConvertToInt(newValue)); - } - else if(index == 1){ - fActionI->SetSourceDirection(G4UIcommand::ConvertTo3Vector(newValue)); - } - else if(index == 2){ - fActionI->SetSourceType(newValue); - } - else if(index == 3){ - fActionI->SetBeamspotRadius(G4UIcommand::ConvertToDouble(newValue)); - } - else if(index == 4){ - fActionI->SetBeamspotRadius0(G4UIcommand::ConvertToDouble(newValue)); - } - else if(index == 5){ - fActionI->SetBeamspotType(newValue); - } - else if(index == 6){ - fActionI->SetIsotropicMode(G4UIcommand::ConvertToInt(newValue)); - } - else if(index == 7){ - G4ThreeVector vec = G4UIcommand::ConvertTo3Vector(newValue); - fActionI->SetEnergyLimits(vec.getX(), vec.getY()); - } - else if(index == 8){ - fActionI->ReadReactionFile(newValue); - } - else if(index == 9){ - fActionI->ReadEnergyFile(newValue); - } - else if(index == 10){ - fActionI->AddDiscreteEnergy(newValue); - } - else if(index == 11){ - fActionI->Test(newValue); - } - else if(index == 12){ - fActionI->Reset(); - } - else if(index == 13){ - fActionI->SetInterpolationMethod(newValue); - } - else if(index == 14){ - fActionI->SetBeamEnergy(G4UIcommand::ConvertToDouble(newValue)); - } - else if(index == 15){ - fActionI->SetBeamEnergySigma(newValue); - } -} -*/ \ No newline at end of file diff --git a/source/nDetRunAction.cc b/source/nDetRunAction.cc index 6e177ce..2c094a9 100644 --- a/source/nDetRunAction.cc +++ b/source/nDetRunAction.cc @@ -305,6 +305,7 @@ bool nDetRunAction::processDetector(nDetDetector* det){ pmtResponse *pmtL = cmL->getPmtResponse(); pmtResponse *pmtR = cmR->getPmtResponse(); + //std::cout<<"!!! Process !!! "<GetCenterOfMass()->getNumColumns()<<" "<getNumColumns()<GetDetectorParameters(); centerOfMass *cmI = imp->getCenterOfMass(); + //std::cout<<"!!! Process !!! "<GetCenterOfMass()->getNumColumns()<<" "<getNumColumns()<setSegmentedPmt(¶ms); cmI->loadGainMatrix("hamamatsuH12700A_LA0967.dat"); @@ -624,10 +626,12 @@ bool nDetRunAction::processStartDetector(nDetDetector* det, double &startTime){ } bool nDetRunAction::processStartImplant(nDetImplant* imp, double &startTime){ + //std::cout<<"!!! Start !!! "<GetCenterOfMass()->getNumColumns()<<" "<getCenterOfMass()->getNumColumns()<::iterator iter = userImplants.begin(); iter != userImplants.end(); iter++){ + //std::cout<<"!!! End !!! "<GetCenterOfMass()->getNumColumns()<<" "<getCenterOfMass()->getNumColumns()<::iterator iter = userImplants.begin(); iter != userImplants.end(); iter++){ + //std::cout<<"!!! Detector !!! "<GetCenterOfMass()->getNumColumns()<<" "<getCenterOfMass()->getNumColumns()<ApplyCommand(command); + //std::cout<<"!! Detector !! "<GetCenterOfMass()->getNumColumns()< Date: Wed, 29 Dec 2021 15:58:47 -0500 Subject: [PATCH 08/17] completed segmented, tapered light guide --- include/nDetDetector.hh | 58 +----------- mac/pspmt.mac | 3 + source/CMakeLists.txt | 2 +- source/nDetConstructionMessenger.cc | 4 +- source/nDetDetector.cc | 132 ++++++++++++++-------------- source/nDetDetectorLayer.cc | 4 +- source/nDetDetectorMessenger.cc | 3 +- source/nDetMaterials.cc | 32 +++---- source/nDetParticleSource.cc | 9 +- 9 files changed, 99 insertions(+), 148 deletions(-) diff --git a/include/nDetDetector.hh b/include/nDetDetector.hh index 7479b2c..a776574 100644 --- a/include/nDetDetector.hh +++ b/include/nDetDetector.hh @@ -3,7 +3,6 @@ #include "globals.hh" #include "G4RotationMatrix.hh" -#include "G4VPVParameterisation.hh" #include "gdmlSolid.hh" #include "centerOfMass.hh" @@ -40,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(10.),dSegMaterial(""){ } /** Initialize the detector parameter messenger for this class * @note Since there may be multiple detectors in any given setup, the nDetDetectorMessenger class @@ -1049,19 +1048,6 @@ protected: 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 - - ////// - //These variables are for a segmented light guide - ////// - /*G4int fXseg; - G4int fYseg; - G4double fspacing; - G4double ftopWidth; - G4double ftopThick; - G4double fbotWidth; - G4double fbotThick; - G4double fzThick; - G4String fSegMaterial;*/ bool checkOverlaps; ///< Flag indicating that Geant should check for overlaps between all placed objects @@ -1126,47 +1112,5 @@ protected: }; -/** @class LightGuideParameterisation - * @brief Used to construct a segmented and tapered light guide - * @author Ian Cox (icox2@vols.utk.edu) - * @date December 22, 2021 - */ - -class LightGuideParameterisation: public G4VPVParameterisation{ - public: - LightGuideParameterisation(G4int Xseg, G4int Yseg, G4double spacing, G4double topWidth, G4double topThick, G4double botWidth, G4double botThick, G4double zThick); - ~LightGuideParameterisation(); - - void ComputeTransformation (const G4int copyNo, G4VPhysicalVolume* physVol) const; - void ComputeDimensions (G4Trap& segment, const G4int copyNo, const G4VPhysicalVolume* physVol) const override; - - private: - G4int m_Xseg; - G4int m_Yseg; - G4double m_spacing; - G4double m_xStart; - G4double m_yStart; - G4double m_zStart; - G4double m_topWidth; - G4double m_topThick; - G4double m_botWidth; - G4double m_botThick; - G4double m_zThick; -}; - - class ChamberParameterisation: public G4VPVParameterisation{ - public: - ChamberParameterisation(G4int NoChambers, G4double startZ, G4double spacing, G4double widthChamber,G4double lenInitial,G4double lenFinal); - ~ChamberParameterisation(); - void ComputeTransformation (const G4int copyNo, G4VPhysicalVolume* physVol) const; - void ComputeDimensions (G4Box& trackerLayer, const G4int copyNo, const G4VPhysicalVolume* physVol) const; - - private: - G4double fStartZ; - G4double fspacing; - G4double fHalfLengthFirst; - G4double fHalfLengthIncr; - G4double fHalfWidth; - }; #endif diff --git a/mac/pspmt.mac b/mac/pspmt.mac index 7fca48d..2d5a49f 100644 --- a/mac/pspmt.mac +++ b/mac/pspmt.mac @@ -67,6 +67,9 @@ /nDet/implant/addDiffuserLayer 50 50 0.1 #/nDet/implant/addLightGuide 50 50 50 50 5 +/nDet/segLightGuide/thickness 10 +/nDet/implant/setSegmentedLightGuide 25 25 10 50 50 20 20 0.1 G4_Pyrex_Glass + # Update the detector. /nDet/implant/update diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index c085c03..837484c 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -32,7 +32,7 @@ set(NextSimDetectorSources nDetMaterials.cc nDetMaterialsMessenger.cc nDetConstr Polyhedron.cc IS530_Chamber.cc IS530_Plastic.cc Tape.cc CloverQuadBuchDetector.cc CloverQuadDetector.cc CloverSingleBuchDetector.cc CloverSingleDetector.cc ) -set(NextSimGeneratorSources nDetParticleSource.cc nDetParticleSourceMessenger.cc G4Implant.cc) +set(NextSimGeneratorSources nDetParticleSource.cc nDetParticleSourceMessenger.cc) set(NextSimPeripheralSources optionHandler.cc termColors.cc) #Add the sources to the library. diff --git a/source/nDetConstructionMessenger.cc b/source/nDetConstructionMessenger.cc index a97369b..e2a208a 100644 --- a/source/nDetConstructionMessenger.cc +++ b/source/nDetConstructionMessenger.cc @@ -156,7 +156,7 @@ void nDetConstructionMessenger::addAllCommands(){ addCommand(new G4UIcmdWithoutParameter("/nDet/implant/printAll", this)); addGuidance("Print construction parameters for all defined implants"); - addCommand(new G4UIcmdWithABool("/nDet/implant/setSegmentedLightGuide", this)); + 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> "); } @@ -329,7 +329,7 @@ void nDetConstructionMessenger::SetNewChildValue(G4UIcommand* command, G4String } //LightGuideParameterisation commands - else if(index == 28 && newValue){ + else if(index == 28){ fDetector->AddSegmentedLightGuide(newValue); } } diff --git a/source/nDetDetector.cc b/source/nDetDetector.cc index ccdb972..9834476 100644 --- a/source/nDetDetector.cc +++ b/source/nDetDetector.cc @@ -7,7 +7,6 @@ #include "G4SubtractionSolid.hh" #include "G4UnionSolid.hh" #include "G4LogicalSkinSurface.hh" -#include "G4PVParameterised.hh" #include "G4Tubs.hh" #include "G4Box.hh" @@ -587,7 +586,7 @@ nDetImplant::nDetImplant(nDetConstruction *detector, nDetMaterials *matptr) : nD assembly_logV(NULL), assembly_physV(NULL), layerSizeX(0), layerSizeY(0), offsetZ(0), parentCopyNum(0), firstSegmentCopyNum(0), lastSegmentCopyNum(0), - checkOverlaps(false) + checkOverlaps(true) { copyCenterOfMass(*detector->GetCenterOfMass()); //This has been adjusted materials = matptr; @@ -718,7 +717,7 @@ G4LogicalVolume *nDetImplant::constructAssembly(){ // Account for the size of the PSPMT assemblyWidth = std::max(assemblyWidth, pmtWidth); assemblyHeight = std::max(assemblyHeight, pmtHeight); - assemblyLength += 2*(fGreaseThickness+fWindowThickness+fSensitiveThickness); + assemblyLength += 2*(2*fGreaseThickness+fWindowThickness+fSensitiveThickness+dzThick); // Account for the additional component layers for(std::vector::iterator iter = userLayers.begin(); iter != userLayers.end(); iter++){ @@ -962,18 +961,80 @@ void nDetImplant::applyLightGuide(const G4double &x1, const G4double &x2, const // Offset the other layers to account for the light-guide layerSizeX = x2; layerSizeY = y2; - offsetZ += thickness; + 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 seg_log = new G4LogicalVolume(seg_solid,lg_mat,"seg_log"); - G4VPVParameterisation* lightGuideParam = new LightGuideParameterisation(Xseg,Yseg,spacing,topWidth,topThick,botWidth,botThick,zThick); - G4VPhysicalVolume* lightGuide = new G4PVParameterised("lg_para",seg_log,assembly_logV,kXAxis,numSegs,lightGuideParam); + auto lg_box = new G4Box("lg_box",topWidth/2.,topThick/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;copyNoSetVisAttributes(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, wrappingOpSurf); + } + } + G4PVPlacement *lightGuideBox = addBackComponent(lg_log,offsetZ+zThick/2.,name); + offsetZ+=zThick; return; } @@ -1013,60 +1074,3 @@ void nDetImplant::loadLightGuide(gdmlSolid *solid, const G4ThreeVector &rotation fTrapezoidLength = solid->getLength()*mm; } -LightGuideParameterisation::LightGuideParameterisation(G4int Xseg, G4int Yseg, G4double spacing, G4double topWidth, G4double topThick, G4double botWidth, G4double botThick, G4double zThick): - G4VPVParameterisation(), - m_Xseg(Xseg), - m_Yseg(Yseg), - m_spacing(spacing), - m_xStart(double(Xseg)*botWidth/2.+spacing*(Xseg/2)), - m_yStart(double(Yseg)*botThick/2.+spacing*(Yseg/2)), - m_zStart(0.), - m_topWidth(topWidth), - m_topThick(topThick), - m_botWidth(botWidth), - m_botThick(botThick), - m_zThick(zThick) - { - G4cout<<"Building Light Guide Parametrisation"<SetTranslation(origin); - physVol->SetRotation(0); -} - -void LightGuideParameterisation::ComputeDimensions(G4Trap& segment, const G4int copyNo, const G4VPhysicalVolume* physVol) const{ - G4double xposb = (copyNo%m_Xseg-m_Xseg)*(m_botWidth); - G4double yposb = (copyNo/m_Yseg-m_Yseg)*(m_botThick); - G4double xpost = (copyNo%m_Xseg-m_Xseg)*(m_topWidth); - G4double ypost = (copyNo/m_Yseg-m_Yseg)*(m_topThick); - G4double zpos = 0.; - G4double pTheta; - if(xposb<0) - pTheta = -1*atan((sqrt(pow(xpost,2)+pow(ypost,2))-sqrt(pow(xposb,2)+pow(yposb,2)))/(m_zThick)); - else - pTheta = atan((sqrt(pow(xpost,2)+pow(ypost,2))-sqrt(pow(xposb,2)+pow(yposb,2)))/(m_zThick)); - G4double pPhi = atan((ypost-yposb+0.0000001)/(xpost-xposb)); - segment.SetAllParameters( - m_zThick/2., // pDz Half z length - pTheta, //pTheta Polar angle of the line joining the centers of the faces at -/+ pDz - pPhi, //pPhi Azimuthal angle of the line joining the center of the face at -pDz to the center of the face at +pDz - m_botThick/2., //pDy1 Half y length at -pDz - m_botWidth/2., //pDx1 Half x length of the side at y=-pDy1 of the face at -pDz - m_botWidth/2., //pDx2 Half x length of the side at y=+pDy1 of the face at -pDz - 0*degree, //pAlp1 Angle with respect to the y-axis from the center of the side (lower endcap) - m_topThick/2., //pDy2 Half y length at +pDz - m_topWidth/2., //pDx3 Half x length of the side at y=-pDy2 of the face at -pDz - m_topWidth/2., //pDx4 Half x length of the side at y=+pDy2 of the face at -pDz - 0*degree //pAlp2 Angle with respect to the y-axis from the center of the side (upper endcap) - ); -} \ No newline at end of file diff --git a/source/nDetDetectorLayer.cc b/source/nDetDetectorLayer.cc index afe0835..3ec7f1c 100644 --- a/source/nDetDetectorLayer.cc +++ b/source/nDetDetectorLayer.cc @@ -109,14 +109,13 @@ segLightGuideLayer::~segLightGuideLayer(){ bool segLightGuideLayer::decodeArgs(){ fXseg = int(strtod(args.at(0).c_str(), NULL)); - fXseg = int(strtod(args.at(1).c_str(), NULL)); + fYseg = int(strtod(args.at(1).c_str(), NULL)); fzThick = strtod(args.at(2).c_str(), NULL); ftopWidth = strtod(args.at(3).c_str(), NULL); ftopThick = strtod(args.at(4).c_str(), NULL); fbotWidth = strtod(args.at(5).c_str(), NULL); fbotThick = strtod(args.at(6).c_str(), NULL); fspacing = strtod(args.at(7).c_str(), NULL); - G4cout<<"Decoded Arguments in segLightGuideLayer"<applyGreaseLayer(); obj->applySegmentedLightGuide(fXseg, fYseg, fspacing, ftopWidth, ftopThick, fbotWidth, fbotThick, fzThick); } diff --git a/source/nDetDetectorMessenger.cc b/source/nDetDetectorMessenger.cc index 72ea8a2..1facd5d 100644 --- a/source/nDetDetectorMessenger.cc +++ b/source/nDetDetectorMessenger.cc @@ -190,7 +190,7 @@ void nDetDetectorMessenger::addAllCommands(){ // Segmented Light Guide commands ///////////////////////////////////////////// - addDirectory("/nDet/segLightGuide","Segmented Light Guide Geometry"); + addDirectory("/nDet/segLightGuide/","Segmented Light Guide Geometry"); addCommand(new G4UIcmdWithADouble("/nDet/segLightGuide/thickness",this)); addGuidance("Defines the z thickness of the segmented light guide"); @@ -414,6 +414,7 @@ void nDetDetectorMessenger::SetNewChildValue(G4UIcommand* command, G4String newV else if(index == 52){ G4double val = command->ConvertToDouble(newValue); fDetector->setSegZThick(val); + std::cout<<"Setting Z thickness to "<ConvertToDouble(newValue); diff --git a/source/nDetMaterials.cc b/source/nDetMaterials.cc index 7ce44e2..c6ca51f 100644 --- a/source/nDetMaterials.cc +++ b/source/nDetMaterials.cc @@ -873,10 +873,10 @@ void nDetMaterials::defineScintillators(){ // YAP YAlO3 ///////////////////////////////////////////////////////////////// - fYSO = new G4Material("YSO", 4.5*g/cm3, 3); - fYSO->AddElement(fY, 0.25); - fYSO->AddElement(fSi, 0.125); - fYSO->AddElement(fO, 0.625); + fYAP = new G4Material("YAP", 4.5*g/cm3, 3); + fYAP->AddElement(fY, 0.25); + fYAP->AddElement(fSi, 0.125); + fYAP->AddElement(fO, 0.625); 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, @@ -890,20 +890,20 @@ void nDetMaterials::defineScintillators(){ 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 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_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 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_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 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.80, 1.80}; //Data taken from https://www.advatech-uk.co.uk/yso_ce.html - G4double Absorption_YAP[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 + G4double RefIndex_YAP[2] = {1.80, 1.80}; //Data taken from https://www.advatech-uk.co.uk/YAP_ce.html + G4double Absorption_YAP[2] = {2.57*cm, 2.57*cm}; // this is found in: Large size LSO:Ce and YAP:Ce scintillators for 50 MeV range /spl gamma/-ray detector fYAPMPT = new G4MaterialPropertiesTable(); - fYAPMPT->AddProperty("RINDEX", photonEnergy_YAP2, RefIndex_YSO, 2); - fYAPMPT->AddProperty("ABSLENGTH", photonEnergy_YAP2, Absorption_YSO, 2); - fYAPMPT->AddProperty("FASTCOMPONENT", photonEnergy_YAP, ScintilFast_YSO, 44); + 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", 24000/MeV); // Photon yield as found in paper above for 137Cs fYAPMPT->AddConstProperty("RESOLUTIONSCALE", 1.0); // Intrinsic resolution @@ -916,16 +916,16 @@ void nDetMaterials::defineScintillators(){ G4double protonYield_YAP[36]; G4double ionYield_YAP[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. + // 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_YSO, 36)->SetSpline(true); - fYAPMPT->AddProperty("PROTONSCINTILLATIONYIELD", particleEnergy, protonYield_YSO, 36)->SetSpline(true); - fYAPMPT->AddProperty("IONSCINTILLATIONYIELD", particleEnergy, ionYield_YSO, 36)->SetSpline(true); + 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); diff --git a/source/nDetParticleSource.cc b/source/nDetParticleSource.cc index 6132bd0..e9c678d 100644 --- a/source/nDetParticleSource.cc +++ b/source/nDetParticleSource.cc @@ -18,7 +18,6 @@ #include "G4Gamma.hh" #include "G4Alpha.hh" #include "G4Ions.hh" -#include "G4Implant.hh" #include "G4OpticalPhoton.hh" #include "G4Electron.hh" #include "Randomize.hh" @@ -155,8 +154,8 @@ bool nDetParticleSource::SetSourceType(const G4String &str){ SetNeutronBeam(beamEnergy); else if(typeName == "alpha") SetAlphaBeam(beamEnergy); - else if(typeName == "ion") - SetIonBeam(beamEnergy); + /*else if(typeName == "ion") + SetIonBeam(beamEnergy);*/ else if(typeName == "gamma") SetGammaRayBeam(beamEnergy); else if(typeName == "laser"){ @@ -325,12 +324,12 @@ void nDetParticleSource::SetAlphaBeam(const double &energy_){ SetBeamEnergy(energy_*MeV); } -void nDetParticleSource::SetIonBeam(const double &energy_){ +/*void nDetParticleSource::SetIonBeam(const double &energy_){ std::cout<<"Ion Beam"<SetParticleDefinition(G4Implant::ImplantDefinition()); SetBeamEnergy(energy_*MeV); -} +}*/ /*void nDetParticleSource::SetIonBeam(const G4String &str){ // Expects a space-delimited string of the form: From a61b0cb79f0e7945471c301738f55cf24b3df46b Mon Sep 17 00:00:00 2001 From: icox2 Date: Mon, 3 Jan 2022 12:31:49 -0500 Subject: [PATCH 09/17] fixed light guide thickness issue --- mac/pspmt.mac | 20 +++++++++++--------- source/nDetDetectorLayer.cc | 3 ++- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/mac/pspmt.mac b/mac/pspmt.mac index 2d5a49f..cfb2abd 100644 --- a/mac/pspmt.mac +++ b/mac/pspmt.mac @@ -18,7 +18,7 @@ # Mylar and optical grease thickness. /nDet/implant/setMylarThickness 0.025 -/nDet/implant/setGreaseThickness 1.0 +/nDet/implant/setGreaseThickness 1 # Light /nDet/implant/setDiffuserLength 1.5 @@ -61,14 +61,15 @@ /nDet/implant/setSpectralResponse ~/opt/NEXTSim/spectral/hamamatsuH12700A.root # Set the position and rotation of the detector in the lab frame. -/nDet/implant/setCylindrical 0.5 0 0 -/nDet/implant/setRotation 0 270 0 +/nDet/implant/setPosition 0 0 10 cm +#/nDet/implant/setCylindrical 0.5 0 0 +/nDet/implant/setRotation 0 0 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 25 25 10 50 50 20 20 0.1 G4_Pyrex_Glass +/nDet/implant/setSegmentedLightGuide 25 25 20 50 50 45 45 G4_Pyrex_Glass # Update the detector. @@ -80,7 +81,7 @@ ################ # Set the output filename prefix -/nDet/output/filename test_1m.root +/nDet/output/filename postest60Co.root /nDet/output/title PSPMT, 0.5 MeV, 1 m from detector #/nDet/output/index 69 #/nDet/output/overwrite true @@ -114,8 +115,9 @@ # Available source types: 137Cs 60Co 133Ba 241Am 90Sr 252Cf #/nDet/source/type 252Cf -/nDet/source/type alpha 10 -#/nDet/source/beam gamma 0.25 +#/nDet/source/type alpha 5 +/nDet/source/type 60Co +/nDet/source/shape point #/nDet/source/beam 137Cs #/nDet/source/beam gamma 0.03 @@ -125,7 +127,7 @@ # Optical laser beam. #/nDet/source/beam laser 360 -#/nDet/source/position 0.1 0 -13.5 cm +#/nDet/source/position 20 0 0 cm #/nDet/source/direction 0 0 0 /nDet/source/iso 1 @@ -136,4 +138,4 @@ # RUN CONTROL # ############### -#/run/beamOn 1000 +#/run/beamOn 100000 diff --git a/source/nDetDetectorLayer.cc b/source/nDetDetectorLayer.cc index 3ec7f1c..fe652b5 100644 --- a/source/nDetDetectorLayer.cc +++ b/source/nDetDetectorLayer.cc @@ -99,7 +99,7 @@ std::string lightGuideLayer::syntaxStr() const { /////////////////////////////////////////////////////////////////////////////// segLightGuideLayer::segLightGuideLayer(const -G4String &arg_) : nDetWorldObject(arg_,9), fXseg(0),fYseg(0),fspacing(0.),ftopWidth(0.),ftopThick(0.),fbotWidth(0.),fbotThick(0.),fzThick(0.),fSegMaterial("G4_Pyrex_Glass"){ +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"; } @@ -126,6 +126,7 @@ void segLightGuideLayer::construct(nDetDetector *obj){ void segLightGuideLayer::construct(nDetImplant *obj){ obj->applyGreaseLayer(); obj->applySegmentedLightGuide(fXseg, fYseg, fspacing, ftopWidth, ftopThick, fbotWidth, fbotThick, fzThick); + obj->setSegZThick(fzThick); } std::string segLightGuideLayer::syntaxStr() const{ From 44148d0acc02b98be3a18a059ca7d5daa241ac4f Mon Sep 17 00:00:00 2001 From: icox2 Date: Mon, 3 Jan 2022 16:16:27 -0500 Subject: [PATCH 10/17] fixed yap scintillator --- include/nDetDetector.hh | 2 +- mac/pspmt.mac | 12 ++++++------ source/nDetDetector.cc | 9 +++++---- source/nDetMaterials.cc | 22 +++++++--------------- 4 files changed, 19 insertions(+), 26 deletions(-) diff --git a/include/nDetDetector.hh b/include/nDetDetector.hh index a776574..7b4e11a 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),dXseg(0),dYseg(0),dspacing(0.),dtopWidth(0.),dtopThick(0.),dbotWidth(0.),dbotThick(0.),dzThick(10.),dSegMaterial(""){ } + 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 diff --git a/mac/pspmt.mac b/mac/pspmt.mac index cfb2abd..e2aac07 100644 --- a/mac/pspmt.mac +++ b/mac/pspmt.mac @@ -24,7 +24,7 @@ /nDet/implant/setDiffuserLength 1.5 # Choose Scintillator -/nDet/implant/setMaterial yso +/nDet/implant/setMaterial yap # PMT segmentation. /nDet/implant/setPmtColumns 8 @@ -35,7 +35,7 @@ ################## # NEXT 2x2x10 in^3 -/nDet/implant/setDetectorLength 1.5 +/nDet/implant/setDetectorLength 0.2 /nDet/implant/setDetectorWidth 5.08 /nDet/implant/setDetectorThickness 50.8 /nDet/implant/setWindowThickness 1. @@ -68,8 +68,8 @@ /nDet/implant/addDiffuserLayer 50 50 0.1 #/nDet/implant/addLightGuide 50 50 50 50 5 -/nDet/segLightGuide/thickness 10 -/nDet/implant/setSegmentedLightGuide 25 25 20 50 50 45 45 G4_Pyrex_Glass +#/nDet/segLightGuide/thickness 10 +/nDet/implant/setSegmentedLightGuide 20 20 5 50 50 45 45 G4_Pyrex_Glass # Update the detector. @@ -81,7 +81,7 @@ ################ # Set the output filename prefix -/nDet/output/filename postest60Co.root +/nDet/output/filename yapAirLG60Co.root /nDet/output/title PSPMT, 0.5 MeV, 1 m from detector #/nDet/output/index 69 #/nDet/output/overwrite true @@ -138,4 +138,4 @@ # RUN CONTROL # ############### -#/run/beamOn 100000 +#/run/beamOn 500000 diff --git a/source/nDetDetector.cc b/source/nDetDetector.cc index 9834476..58b71d9 100644 --- a/source/nDetDetector.cc +++ b/source/nDetDetector.cc @@ -718,6 +718,7 @@ G4LogicalVolume *nDetImplant::constructAssembly(){ assemblyWidth = std::max(assemblyWidth, pmtWidth); assemblyHeight = std::max(assemblyHeight, pmtHeight); assemblyLength += 2*(2*fGreaseThickness+fWindowThickness+fSensitiveThickness+dzThick); + std::cout<<"z thickness "<::iterator iter = userLayers.begin(); iter != userLayers.end(); iter++){ @@ -785,13 +786,12 @@ void nDetImplant::constructPSPmt(){ grease_logV->SetVisAttributes(materials->visGrease); //addMirroredComponents(grease_physV[0], grease_physV[1], grease_logV, greaseZ, "Grease"); - G4PVPlacement *greaseLogical = addBackComponent(grease_logV, greaseZ, "Grease"); //This might need to be edited for the distance... not sure how exactly one can automatically fit it to edge of detector.. maybe needs phys volume + G4PVPlacement *greaseLogical = addBackComponent(grease_logV, greaseZ, "Grease1"); if(!fPolishedInterface){ for(std::vector::iterator iter = scintBody_physV.begin(); iter != scintBody_physV.end(); iter++){ - new G4LogicalBorderSurface("GreaseInterface", (*iter), grease_physV[0], materials->fGreaseOpSurf); - new G4LogicalBorderSurface("GreaseInterface", (*iter), grease_physV[1], materials->fGreaseOpSurf); + new G4LogicalBorderSurface("GreaseInterface", (*iter), greaseLogical, materials->fGreaseOpSurf); } } @@ -885,7 +885,7 @@ void nDetImplant::applyGreaseLayer(const G4double &x, const G4double &y, double // Add the optical grease to the assembly //addMirroredComponents(grease_logV, offsetZ+thickness/2, "Grease"); - G4PVPlacement *greaseLogical = addBackComponent(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; @@ -972,6 +972,7 @@ void nDetImplant::applySegmentedLightGuide(G4int Xseg, G4int Yseg, G4double spac 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 diff --git a/source/nDetMaterials.cc b/source/nDetMaterials.cc index c6ca51f..fe64882 100644 --- a/source/nDetMaterials.cc +++ b/source/nDetMaterials.cc @@ -377,14 +377,6 @@ void nDetMaterials::defineMaterials(){ // Lab vacuum fVacuum = nist.searchForMaterial("G4_Galactic"); - // YSO - - /*fYSO = new G4Material("YSO",4.5*g/cm3, 3); //Originally listed as 2.7 - fYSO->AddElement(fY,2); - fYSO->AddElement(fO,5); - fYSO->AddElement(fSi,1); - - materialList["yso"] = fYSO;*/ ///////////////////////////////////////////////////////////////// // Teflon (C2F4)n @@ -873,10 +865,10 @@ void nDetMaterials::defineScintillators(){ // YAP YAlO3 ///////////////////////////////////////////////////////////////// - fYAP = new G4Material("YAP", 4.5*g/cm3, 3); - fYAP->AddElement(fY, 0.25); - fYAP->AddElement(fSi, 0.125); - fYAP->AddElement(fO, 0.625); + 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, @@ -897,15 +889,15 @@ void nDetMaterials::defineScintillators(){ //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.80, 1.80}; //Data taken from https://www.advatech-uk.co.uk/YAP_ce.html - G4double Absorption_YAP[2] = {2.57*cm, 2.57*cm}; // this is found in: Large size LSO:Ce and YAP:Ce scintillators for 50 MeV range /spl gamma/-ray detector + 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", 24000/MeV); // Photon yield as found in paper above for 137Cs + fYAPMPT->AddConstProperty("SCINTILLATIONYIELD", 26000/MeV); fYAPMPT->AddConstProperty("RESOLUTIONSCALE", 1.0); // Intrinsic resolution fYAPMPT->AddConstProperty("FASTSCINTILLATIONRISETIME", 2.0*ns); From 99450f06f8de152bcaad39acf2b9cf2e274b010b Mon Sep 17 00:00:00 2001 From: icox2 Date: Mon, 10 Jan 2022 11:44:42 -0500 Subject: [PATCH 11/17] adding airMPT for using air wrapping --- include/nDetMaterials.hh | 1 + include/vertilon256.hh | 268 ++++++++++++++++++++++++++++++++ mac/pspmt.mac | 18 +-- mac/pspmt1inLG.mac | 141 +++++++++++++++++ source/nDetDetector.cc | 3 +- source/nDetDetectorMessenger.cc | 4 + source/nDetMaterials.cc | 20 ++- 7 files changed, 443 insertions(+), 12 deletions(-) create mode 100644 include/vertilon256.hh create mode 100644 mac/pspmt1inLG.mac diff --git a/include/nDetMaterials.hh b/include/nDetMaterials.hh index e8f0ae1..5039477 100644 --- a/include/nDetMaterials.hh +++ b/include/nDetMaterials.hh @@ -75,6 +75,7 @@ class nDetMaterials{ G4OpticalSurface* fEsrOpSurf; ///< Optical surface for 3M Enhanced Specular Reflector G4OpticalSurface* fPerfectOpSurf; ///< Optical surface for a perfect reflector G4OpticalSurface* fGreaseOpSurf; ///< Optical surface for optical grease + G4OpticalSurface* fAirOpSurf; ///< Optical surface for air // Visual attributes G4VisAttributes *visAssembly; ///< Visual attributes for the mother assembly 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/pspmt.mac b/mac/pspmt.mac index e2aac07..e9a940c 100644 --- a/mac/pspmt.mac +++ b/mac/pspmt.mac @@ -13,12 +13,12 @@ # 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/implant/setPmtDimensions 25.0 # Mylar and optical grease thickness. /nDet/implant/setMylarThickness 0.025 -/nDet/implant/setGreaseThickness 1 +/nDet/implant/setGreaseThickness 0.5 # Light /nDet/implant/setDiffuserLength 1.5 @@ -35,9 +35,9 @@ ################## # NEXT 2x2x10 in^3 -/nDet/implant/setDetectorLength 0.2 -/nDet/implant/setDetectorWidth 5.08 -/nDet/implant/setDetectorThickness 50.8 +/nDet/implant/setDetectorLength 1 +/nDet/implant/setDetectorWidth 3.08 +/nDet/implant/setDetectorThickness 30.8 /nDet/implant/setWindowThickness 1. /nDet/implant/setNumColumns 20 /nDet/implant/setNumRows 20 @@ -69,7 +69,7 @@ /nDet/implant/addDiffuserLayer 50 50 0.1 #/nDet/implant/addLightGuide 50 50 50 50 5 #/nDet/segLightGuide/thickness 10 -/nDet/implant/setSegmentedLightGuide 20 20 5 50 50 45 45 G4_Pyrex_Glass +/nDet/implant/setSegmentedLightGuide 20 20 10 30.5 30.5 20.8 20.8 G4_Pyrex_Glass # Update the detector. @@ -81,7 +81,7 @@ ################ # Set the output filename prefix -/nDet/output/filename yapAirLG60Co.root +/nDet/output/filename posTest1inLG60Co.root /nDet/output/title PSPMT, 0.5 MeV, 1 m from detector #/nDet/output/index 69 #/nDet/output/overwrite true @@ -103,7 +103,7 @@ /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 @@ -138,4 +138,4 @@ # RUN CONTROL # ############### -#/run/beamOn 500000 +/run/beamOn 200000 diff --git a/mac/pspmt1inLG.mac b/mac/pspmt1inLG.mac new file mode 100644 index 0000000..2b1bf18 --- /dev/null +++ b/mac/pspmt1inLG.mac @@ -0,0 +1,141 @@ +# +# 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 yap + +# PMT segmentation. +/nDet/implant/setPmtColumns 8 +/nDet/implant/setPmtRows 8 + +################## +# DETECTOR SETUP # +################## + +# NEXT 2x2x10 in^3 +/nDet/implant/setDetectorLength 1 +/nDet/implant/setDetectorWidth 3.08 +/nDet/implant/setDetectorThickness 30.8 +/nDet/implant/setWindowThickness 1. +/nDet/implant/setNumColumns 20 +/nDet/implant/setNumRows 20 +/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 air + +# 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 10 cm +#/nDet/implant/setCylindrical 0.5 0 0 +/nDet/implant/setRotation 0 0 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 20 20 10 30.5 30.5 20.8 20.8 G4_Pyrex_Glass + + +# Update the detector. +/nDet/implant/update + + +################ +# OUTPUT SETUP # +################ + +# Set the output filename prefix +/nDet/output/filename yapAirSmallPMT60Co.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 60Co +/nDet/source/shape point +#/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/source/nDetDetector.cc b/source/nDetDetector.cc index 58b71d9..f31e0a1 100644 --- a/source/nDetDetector.cc +++ b/source/nDetDetector.cc @@ -1028,7 +1028,8 @@ void nDetImplant::applySegmentedLightGuide(G4int Xseg, G4int Yseg, G4double spac if(WrappingEnabled()){ auto outer = new G4Trap("outer",zThick/2.,pTheta,pPhi,cellYt/2.+fWrappingThickness/2.,cellXt/2.+fWrappingThickness/2.,cellXt/2.+fWrappingThickness/2.,0*degree,cellYb/2.+fWrappingThickness/2.,cellXb/2.+fWrappingThickness/2.,cellXb/2.+fWrappingThickness/2.,0*degree); auto wrapping = new G4SubtractionSolid("wrapping",outer,seg_solid); - G4LogicalVolume *wrapping_logV = new G4LogicalVolume(wrapping, wrappingMaterial, "wrapping_logV"); + //G4LogicalVolume *wrapping_logV = new G4LogicalVolume(wrapping, wrappingMaterial, "wrapping_logV"); + G4LogicalVolume *wrapping_logV = new G4LogicalVolume(wrapping,materials->fMylar, "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, wrappingOpSurf); diff --git a/source/nDetDetectorMessenger.cc b/source/nDetDetectorMessenger.cc index 1facd5d..51085eb 100644 --- a/source/nDetDetectorMessenger.cc +++ b/source/nDetDetectorMessenger.cc @@ -212,6 +212,9 @@ void nDetDetectorMessenger::addAllCommands(){ 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){ @@ -440,4 +443,5 @@ void nDetDetectorMessenger::SetNewChildValue(G4UIcommand* command, G4String newV G4int val = command->ConvertToInt(newValue); fDetector->setSegY(val); } + else if(index == 59){} } diff --git a/source/nDetMaterials.cc b/source/nDetMaterials.cc index fe64882..86aee16 100644 --- a/source/nDetMaterials.cc +++ b/source/nDetMaterials.cc @@ -93,8 +93,9 @@ void nDetMaterials::initialize(){ opticalSurfaceList["esr"] = fEsrOpSurf; opticalSurfaceList["perfect"] = fPerfectOpSurf; opticalSurfaceList["grease"] = fGreaseOpSurf; + opticalSurfaceList["air"] = fAirOpSurf; - //visAttributesList["air"] = &G4VisAttributes::Invisible; + visAttributesList["air"] = visWrapping; //visAttributesList["vacuum"] = &G4VisAttributes::Invisible; visAttributesList["teflon"] = visWrapping; visAttributesList["ej200"] = visScint; @@ -143,7 +144,7 @@ G4OpticalSurface* nDetMaterials::getUserOpticalSurface(const G4String &name){ 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); @@ -374,6 +375,14 @@ void nDetMaterials::defineMaterials(){ // 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"); @@ -600,6 +609,13 @@ 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); + + isInitialized = true; } From bb8269d1b7372bb2394c54db73b5fc7ffb7fb388 Mon Sep 17 00:00:00 2001 From: icox2 Date: Mon, 10 Jan 2022 16:24:55 -0500 Subject: [PATCH 12/17] added front face reflector.. set to always mylar --- include/nDetDetector.hh | 3 +++ mac/pspmt1inLG.mac | 4 +-- source/nDetDetector.cc | 50 ++++++++++++++++++------------------- source/nDetDetectorLayer.cc | 2 +- source/nDetDetectorTypes.cc | 15 ++++++++--- 5 files changed, 43 insertions(+), 31 deletions(-) diff --git a/include/nDetDetector.hh b/include/nDetDetector.hh index 7b4e11a..8dcfcf7 100644 --- a/include/nDetDetector.hh +++ b/include/nDetDetector.hh @@ -314,11 +314,14 @@ 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 diff --git a/mac/pspmt1inLG.mac b/mac/pspmt1inLG.mac index 2b1bf18..ba2f519 100644 --- a/mac/pspmt1inLG.mac +++ b/mac/pspmt1inLG.mac @@ -35,7 +35,7 @@ ################## # NEXT 2x2x10 in^3 -/nDet/implant/setDetectorLength 1 +/nDet/implant/setDetectorLength 0.2 /nDet/implant/setDetectorWidth 3.08 /nDet/implant/setDetectorThickness 30.8 /nDet/implant/setWindowThickness 1. @@ -69,7 +69,7 @@ /nDet/implant/addDiffuserLayer 50 50 0.1 #/nDet/implant/addLightGuide 50 50 50 50 5 #/nDet/segLightGuide/thickness 10 -/nDet/implant/setSegmentedLightGuide 20 20 10 30.5 30.5 20.8 20.8 G4_Pyrex_Glass +/nDet/implant/setSegmentedLightGuide 20 20 25 30.5 30.5 20.8 20.8 G4_Pyrex_Glass # Update the detector. diff --git a/source/nDetDetector.cc b/source/nDetDetector.cc index f31e0a1..8c26b32 100644 --- a/source/nDetDetector.cc +++ b/source/nDetDetector.cc @@ -271,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); @@ -695,8 +696,11 @@ void nDetImplant::construct(){ 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(); @@ -776,7 +780,7 @@ void nDetImplant::constructPSPmt(){ G4double wrappingThickness = fGreaseThickness + fWindowThickness; // The optical grease layer. - G4PVPlacement *grease_physV[2] = {NULL, NULL}; + G4PVPlacement *greasePhys = NULL; if(fGreaseThickness > 0){ G4double greaseZ = offsetZ + fGreaseThickness/2; @@ -785,13 +789,11 @@ void nDetImplant::constructPSPmt(){ grease_logV->SetVisAttributes(materials->visGrease); - //addMirroredComponents(grease_physV[0], grease_physV[1], grease_logV, greaseZ, "Grease"); - G4PVPlacement *greaseLogical = addBackComponent(grease_logV, greaseZ, "Grease1"); - + 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), greaseLogical, materials->fGreaseOpSurf); + new G4LogicalBorderSurface("GreaseInterface", (*iter), greasePhys, materials->fGreaseOpSurf); } } @@ -799,7 +801,7 @@ void nDetImplant::constructPSPmt(){ scintBody_physV.clear(); } - G4PVPlacement *window_physV[2] = {NULL, NULL}; + G4PVPlacement *windowPhys = NULL; if(fWindowThickness > 0){ // The quartz window G4double windowZ = offsetZ + fGreaseThickness + fWindowThickness/2; @@ -808,8 +810,7 @@ void nDetImplant::constructPSPmt(){ window_logV->SetVisAttributes(materials->visWindow); - //addMirroredComponents(window_physV[0], window_physV[1], window_logV, windowZ, "Quartz"); //not sure if this is needed - G4PVPlacement *window = addBackComponent(window_logV, windowZ, "Quartz"); + windowPhys = addBackComponent(window_logV, windowZ, "Quartz"); } // Build the wrapping. @@ -824,33 +825,31 @@ void nDetImplant::constructPSPmt(){ G4double wrappingZ = offsetZ + fGreaseThickness/2 + fWindowThickness/2; // Place the wrapping around the scintillator. - G4PVPlacement *greaseWrapping_physV[2]; + G4PVPlacement *greaseWrapping_physV; - if(grease_physV[0] && grease_physV[1]){ - new G4LogicalBorderSurface("Wrapping", grease_physV[0], greaseWrapping_physV[0], wrappingOpSurf); - new G4LogicalBorderSurface("Wrapping", grease_physV[1], greaseWrapping_physV[1], wrappingOpSurf); + if(greasePhys){ + new G4LogicalBorderSurface("Wrapping", greasePhys, greaseWrapping_physV, wrappingOpSurf); } - if(window_physV[0] && window_physV[1]){ - new G4LogicalBorderSurface("Wrapping", window_physV[0], greaseWrapping_physV[0], wrappingOpSurf); - new G4LogicalBorderSurface("Wrapping", window_physV[1], greaseWrapping_physV[1], 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); + // 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 + // Move the current offset past the PMT layerSizeX = pmtWidth; layerSizeY = pmtHeight; - offsetZ += fGreaseThickness + fWindowThickness + fSensitiveThickness; + offsetZ += fGreaseThickness + fWindowThickness + fSensitiveThickness; } G4CSGSolid *nDetImplant::getVolume(const G4String &name, const G4double &width, const G4double &height, const G4double &length){ @@ -872,6 +871,7 @@ G4CSGSolid *nDetImplant::getLightGuideVolume(const G4String &name, const G4doubl } void nDetImplant::applyGreaseLayer(){ + std::cout<<"Layer size x "<applyGreaseLayer(layerSizeX, layerSizeY); } @@ -1032,7 +1032,7 @@ void nDetImplant::applySegmentedLightGuide(G4int Xseg, G4int Yseg, G4double spac G4LogicalVolume *wrapping_logV = new G4LogicalVolume(wrapping,materials->fMylar, "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, wrappingOpSurf); + new G4LogicalBorderSurface("Wrapping", seg_place, wrap_place, wrappingOuterOpSurf); } } G4PVPlacement *lightGuideBox = addBackComponent(lg_log,offsetZ+zThick/2.,name); diff --git a/source/nDetDetectorLayer.cc b/source/nDetDetectorLayer.cc index fe652b5..3d7fd40 100644 --- a/source/nDetDetectorLayer.cc +++ b/source/nDetDetectorLayer.cc @@ -124,7 +124,7 @@ void segLightGuideLayer::construct(nDetDetector *obj){ } void segLightGuideLayer::construct(nDetImplant *obj){ - obj->applyGreaseLayer(); + obj->applyGreaseLayer(ftopWidth,ftopThick); obj->applySegmentedLightGuide(fXseg, fYseg, fspacing, ftopWidth, ftopThick, fbotWidth, fbotThick, fzThick); obj->setSegZThick(fzThick); } diff --git a/source/nDetDetectorTypes.cc b/source/nDetDetectorTypes.cc index 9448494..5282865 100644 --- a/source/nDetDetectorTypes.cc +++ b/source/nDetDetectorTypes.cc @@ -356,17 +356,23 @@ void implantType::buildDetector(){ // 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, wrappingMaterial, "wrapping_logV"); + 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); @@ -408,6 +414,7 @@ void implantType::buildDetector(){ // 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); From 94e4694fdb097f6318c47b5a01032942c08e3808 Mon Sep 17 00:00:00 2001 From: icox2 Date: Thu, 13 Jan 2022 11:01:07 -0500 Subject: [PATCH 13/17] hot fix for square source shape.. needs det. width --- include/nDetMaterials.hh | 4 +++ mac/pspmt.mac | 28 ++++++++-------- mac/pspmt1inLG.mac | 26 +++++++-------- source/nDetMaterials.cc | 64 ++++++++++++++++++++++++++++++++++-- source/nDetParticleSource.cc | 1 + 5 files changed, 94 insertions(+), 29 deletions(-) diff --git a/include/nDetMaterials.hh b/include/nDetMaterials.hh index 5039477..59dad9b 100644 --- a/include/nDetMaterials.hh +++ b/include/nDetMaterials.hh @@ -35,6 +35,8 @@ class nDetMaterials{ 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 @@ -49,6 +51,7 @@ class nDetMaterials{ 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 @@ -59,6 +62,7 @@ class nDetMaterials{ 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 diff --git a/mac/pspmt.mac b/mac/pspmt.mac index e9a940c..714e593 100644 --- a/mac/pspmt.mac +++ b/mac/pspmt.mac @@ -13,7 +13,7 @@ # This is important to set for GDML light-guide because # we cannot obtain the information from the model itself. -/nDet/implant/setPmtDimensions 25.0 +/nDet/implant/setPmtDimensions 50.0 # Mylar and optical grease thickness. @@ -24,7 +24,7 @@ /nDet/implant/setDiffuserLength 1.5 # Choose Scintillator -/nDet/implant/setMaterial yap +/nDet/implant/setMaterial gagg # PMT segmentation. /nDet/implant/setPmtColumns 8 @@ -35,12 +35,12 @@ ################## # NEXT 2x2x10 in^3 -/nDet/implant/setDetectorLength 1 -/nDet/implant/setDetectorWidth 3.08 -/nDet/implant/setDetectorThickness 30.8 +/nDet/implant/setDetectorLength 0.1 +/nDet/implant/setDetectorWidth 5.08 +/nDet/implant/setDetectorThickness 50.8 /nDet/implant/setWindowThickness 1. -/nDet/implant/setNumColumns 20 -/nDet/implant/setNumRows 20 +/nDet/implant/setNumColumns 24 +/nDet/implant/setNumRows 24 /nDet/implant/setStart 1 # NEXT 3x3x10 in^3 @@ -51,7 +51,7 @@ #/nDet/implant/setNumRows 6 # Set the wrapping. -/nDet/implant/setWrapping mylar +/nDet/implant/setWrapping air # Load PSPMT gain matrix # NOTE: This MUST be done AFTER calling '/nDet/implant/update' otherwise it will fail @@ -61,15 +61,15 @@ /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 10 cm +/nDet/implant/setPosition 0 0 0 cm #/nDet/implant/setCylindrical 0.5 0 0 -/nDet/implant/setRotation 0 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 20 20 10 30.5 30.5 20.8 20.8 G4_Pyrex_Glass +/nDet/implant/setSegmentedLightGuide 24 24 5 50.8 50.8 45 45 G4_Pyrex_Glass # Update the detector. @@ -81,7 +81,7 @@ ################ # Set the output filename prefix -/nDet/output/filename posTest1inLG60Co.root +/nDet/output/filename posTestGAGGAir90Sr.root /nDet/output/title PSPMT, 0.5 MeV, 1 m from detector #/nDet/output/index 69 #/nDet/output/overwrite true @@ -116,8 +116,8 @@ #/nDet/source/type 252Cf #/nDet/source/type alpha 5 -/nDet/source/type 60Co -/nDet/source/shape point +/nDet/source/type 90Sr +/nDet/source/shape square #/nDet/source/beam 137Cs #/nDet/source/beam gamma 0.03 diff --git a/mac/pspmt1inLG.mac b/mac/pspmt1inLG.mac index ba2f519..6bb2ac4 100644 --- a/mac/pspmt1inLG.mac +++ b/mac/pspmt1inLG.mac @@ -24,7 +24,7 @@ /nDet/implant/setDiffuserLength 1.5 # Choose Scintillator -/nDet/implant/setMaterial yap +/nDet/implant/setMaterial yso # PMT segmentation. /nDet/implant/setPmtColumns 8 @@ -35,12 +35,12 @@ ################## # NEXT 2x2x10 in^3 -/nDet/implant/setDetectorLength 0.2 -/nDet/implant/setDetectorWidth 3.08 -/nDet/implant/setDetectorThickness 30.8 +/nDet/implant/setDetectorLength 1 +/nDet/implant/setDetectorWidth 5.08 +/nDet/implant/setDetectorThickness 50.8 /nDet/implant/setWindowThickness 1. -/nDet/implant/setNumColumns 20 -/nDet/implant/setNumRows 20 +/nDet/implant/setNumColumns 24 +/nDet/implant/setNumRows 24 /nDet/implant/setStart 1 # NEXT 3x3x10 in^3 @@ -51,7 +51,7 @@ #/nDet/implant/setNumRows 6 # Set the wrapping. -/nDet/implant/setWrapping air +/nDet/implant/setWrapping mylar # Load PSPMT gain matrix # NOTE: This MUST be done AFTER calling '/nDet/implant/update' otherwise it will fail @@ -61,15 +61,15 @@ /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 10 cm +/nDet/implant/setPosition 0 0 0 cm #/nDet/implant/setCylindrical 0.5 0 0 -/nDet/implant/setRotation 0 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 20 20 25 30.5 30.5 20.8 20.8 G4_Pyrex_Glass +/nDet/implant/setSegmentedLightGuide 24 24 5 50 50 25 25 G4_Pyrex_Glass # Update the detector. @@ -81,7 +81,7 @@ ################ # Set the output filename prefix -/nDet/output/filename yapAirSmallPMT60Co.root +/nDet/output/filename ysoMylarSmallPMT90Sr.root /nDet/output/title PSPMT, 0.5 MeV, 1 m from detector #/nDet/output/index 69 #/nDet/output/overwrite true @@ -116,8 +116,8 @@ #/nDet/source/type 252Cf #/nDet/source/type alpha 5 -/nDet/source/type 60Co -/nDet/source/shape point +/nDet/source/type 90Sr +/nDet/source/shape square #/nDet/source/beam 137Cs #/nDet/source/beam gamma 0.03 diff --git a/source/nDetMaterials.cc b/source/nDetMaterials.cc index 86aee16..b47051a 100644 --- a/source/nDetMaterials.cc +++ b/source/nDetMaterials.cc @@ -52,6 +52,8 @@ nDetMaterials::~nDetMaterials(){ delete fLaBr3MPT; delete fYAP; delete fYAPMPT; + delete fGAGG; + delete fGAGGMPT; } delete messenger; } @@ -71,12 +73,14 @@ void nDetMaterials::initialize(){ 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; @@ -372,6 +376,8 @@ void nDetMaterials::defineMaterials(){ 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"); @@ -937,12 +943,66 @@ void nDetMaterials::defineScintillators(){ 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 e9c678d..c3dc161 100644 --- a/source/nDetParticleSource.cc +++ b/source/nDetParticleSource.cc @@ -750,6 +750,7 @@ void nDetParticleSource::setBeamProfile(G4SingleParticleSource *src){ else if(beamspotType == 4){ // Square profile pos->SetPosDisType("Plane"); pos->SetPosDisShape("Square"); + beamspot = 25.; pos->SetHalfX(beamspot); pos->SetHalfY(beamspot); } From 9fc4f3d673af223bd9f42a0205f9dbdc2efa169d Mon Sep 17 00:00:00 2001 From: icox2 Date: Fri, 12 Aug 2022 12:36:46 -0400 Subject: [PATCH 14/17] Adding option to use Sipm array logic for calculating the reconstructed position.. ideal for MTAS implant detector --- include/centerOfMass.hh | 8 ++ include/nDetDetector.hh | 4 + mac/fdsiImplant.mac | 142 +++++++++++++++++++++++++++ mac/mtasImplant.mac | 143 ++++++++++++++++++++++++++++ mac/pspmt.mac | 13 +-- mac/pspmt1inLG.mac | 3 +- source/centerOfMass.cc | 22 +++++ source/nDetConstructionMessenger.cc | 9 ++ source/nDetDetector.cc | 2 +- source/nDetDetectorMessenger.cc | 24 +++-- source/nDetMaterials.cc | 4 +- source/nDetParticleSource.cc | 1 - source/nDetRunAction.cc | 23 +++-- 13 files changed, 373 insertions(+), 25 deletions(-) create mode 100644 mac/fdsiImplant.mac create mode 100644 mac/mtasImplant.mac diff --git a/include/centerOfMass.hh b/include/centerOfMass.hh index 56f97f3..596a6ad 100644 --- a/include/centerOfMass.hh +++ b/include/centerOfMass.hh @@ -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/nDetDetector.hh b/include/nDetDetector.hh index 8dcfcf7..50602dd 100644 --- a/include/nDetDetector.hh +++ b/include/nDetDetector.hh @@ -271,8 +271,11 @@ public: 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) @@ -1041,6 +1044,7 @@ public: 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 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/mtasImplant.mac b/mac/mtasImplant.mac new file mode 100644 index 0000000..615bf95 --- /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 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 10000 diff --git a/mac/pspmt.mac b/mac/pspmt.mac index 714e593..8730764 100644 --- a/mac/pspmt.mac +++ b/mac/pspmt.mac @@ -24,7 +24,7 @@ /nDet/implant/setDiffuserLength 1.5 # Choose Scintillator -/nDet/implant/setMaterial gagg +/nDet/implant/setMaterial yso # PMT segmentation. /nDet/implant/setPmtColumns 8 @@ -35,7 +35,7 @@ ################## # NEXT 2x2x10 in^3 -/nDet/implant/setDetectorLength 0.1 +/nDet/implant/setDetectorLength 1.2 /nDet/implant/setDetectorWidth 5.08 /nDet/implant/setDetectorThickness 50.8 /nDet/implant/setWindowThickness 1. @@ -51,7 +51,7 @@ #/nDet/implant/setNumRows 6 # Set the wrapping. -/nDet/implant/setWrapping air +/nDet/implant/setWrapping perfect # Load PSPMT gain matrix # NOTE: This MUST be done AFTER calling '/nDet/implant/update' otherwise it will fail @@ -81,7 +81,7 @@ ################ # Set the output filename prefix -/nDet/output/filename posTestGAGGAir90Sr.root +/nDet/output/filename posTestYSOPerfect90Sr.root /nDet/output/title PSPMT, 0.5 MeV, 1 m from detector #/nDet/output/index 69 #/nDet/output/overwrite true @@ -117,7 +117,8 @@ #/nDet/source/type alpha 5 /nDet/source/type 90Sr -/nDet/source/shape square +/nDet/source/spot 5 #half-width for beam +/nDet/source/shape circle #/nDet/source/beam 137Cs #/nDet/source/beam gamma 0.03 @@ -138,4 +139,4 @@ # RUN CONTROL # ############### -/run/beamOn 200000 +#/run/beamOn 200000 diff --git a/mac/pspmt1inLG.mac b/mac/pspmt1inLG.mac index 6bb2ac4..d4f83a6 100644 --- a/mac/pspmt1inLG.mac +++ b/mac/pspmt1inLG.mac @@ -66,10 +66,10 @@ /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 50 25 25 G4_Pyrex_Glass +/nDet/implant/addDiffuserLayer 25 25 1 # Update the detector. @@ -117,6 +117,7 @@ #/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 diff --git a/source/centerOfMass.cc b/source/centerOfMass.cc index 499b8d5..586143b 100644 --- a/source/centerOfMass.cc +++ b/source/centerOfMass.cc @@ -75,6 +75,28 @@ double centerOfMass::getReconstructedY() const { return ((anodeCurrent[1]+anodeCurrent[2])-(anodeCurrent[3]+anodeCurrent[0]))/(anodeCurrent[0]+anodeCurrent[1]+anodeCurrent[2]+anodeCurrent[3]); } +double centerOfMass::getSipmX() const { + double total = 0,x=0; + for(int i=0;i 0 ? Ncol : 1); diff --git a/source/nDetConstructionMessenger.cc b/source/nDetConstructionMessenger.cc index e2a208a..cc736e2 100644 --- a/source/nDetConstructionMessenger.cc +++ b/source/nDetConstructionMessenger.cc @@ -11,6 +11,7 @@ #include "G4UIcmdWith3Vector.hh" #include "G4UIcmdWith3VectorAndUnit.hh" #include "G4UIcmdWithADouble.hh" +#include "G4UIcmdWithABool.hh" #include "G4UIcmdWithAnInteger.hh" #include "G4UIcmdWithoutParameter.hh" #include "G4UIcmdWithABool.hh" @@ -159,6 +160,9 @@ void nDetConstructionMessenger::addAllCommands(){ 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){ @@ -332,5 +336,10 @@ void nDetConstructionMessenger::SetNewChildValue(G4UIcommand* command, G4String 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/nDetDetector.cc b/source/nDetDetector.cc index 8c26b32..114eaa6 100644 --- a/source/nDetDetector.cc +++ b/source/nDetDetector.cc @@ -591,7 +591,7 @@ nDetImplant::nDetImplant(nDetConstruction *detector, nDetMaterials *matptr) : nD { copyCenterOfMass(*detector->GetCenterOfMass()); //This has been adjusted materials = matptr; - //std::cout<<"!! Implant !! "<GetDetectorParameters().GetNumPmtColumns()<GetDetectorParameters().GetReconLogic(); } nDetImplant::~nDetImplant(){ diff --git a/source/nDetDetectorMessenger.cc b/source/nDetDetectorMessenger.cc index 51085eb..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" @@ -178,13 +179,15 @@ void nDetDetectorMessenger::addAllCommands(){ 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 @@ -415,33 +418,38 @@ void nDetDetectorMessenger::SetNewChildValue(G4UIcommand* command, G4String newV 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 == 54){ + else if(index == 55){ G4double val = command->ConvertToDouble(newValue); fDetector->setSegTopWidth(val); } - else if(index == 55){ + else if(index == 56){ G4double val = command->ConvertToDouble(newValue); fDetector->setSegBotThick(val); } - else if(index == 56){ + else if(index == 57){ G4double val = command->ConvertToDouble(newValue); fDetector->setSegBotWidth(val); } - else if(index == 57){ + else if(index == 58){ G4int val = command->ConvertToInt(newValue); fDetector->setSegX(val); } - else if(index == 58){ + else if(index == 59){ G4int val = command->ConvertToInt(newValue); fDetector->setSegY(val); } - else if(index == 59){} + else if(index == 60){} } diff --git a/source/nDetMaterials.cc b/source/nDetMaterials.cc index b47051a..fd55b12 100644 --- a/source/nDetMaterials.cc +++ b/source/nDetMaterials.cc @@ -495,7 +495,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}; @@ -515,6 +515,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); diff --git a/source/nDetParticleSource.cc b/source/nDetParticleSource.cc index c3dc161..e9c678d 100644 --- a/source/nDetParticleSource.cc +++ b/source/nDetParticleSource.cc @@ -750,7 +750,6 @@ void nDetParticleSource::setBeamProfile(G4SingleParticleSource *src){ else if(beamspotType == 4){ // Square profile pos->SetPosDisType("Plane"); pos->SetPosDisShape("Square"); - beamspot = 25.; pos->SetHalfX(beamspot); pos->SetHalfY(beamspot); } diff --git a/source/nDetRunAction.cc b/source/nDetRunAction.cc index 2c094a9..9ad37b0 100644 --- a/source/nDetRunAction.cc +++ b/source/nDetRunAction.cc @@ -19,7 +19,7 @@ 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){ @@ -554,8 +554,15 @@ bool nDetRunAction::processImplant(nDetImplant* imp){ // 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]); - debugData.reconDetComX[0] = cmI->getReconstructedX(); - debugData.reconDetComY[0] = cmI->getReconstructedY(); + // std::cout<<"!! Checking Logic :"<getSipmX(); + debugData.reconDetComY[0] = cmI->getSipmY(); + } + else{ + debugData.reconDetComX[0] = cmI->getReconstructedX(); + debugData.reconDetComY[0] = cmI->getReconstructedY(); + } //std::cout<<"recon "<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; From be72eead56ef1b8fb772662155fe13f6d37c6a7e Mon Sep 17 00:00:00 2001 From: icox2 Date: Fri, 12 Aug 2022 15:45:01 -0400 Subject: [PATCH 15/17] small fixes to Sipm array logic, should be fully operational --- mac/mtasImplant.mac | 2 +- source/centerOfMass.cc | 5 +++-- source/nDetRunAction.cc | 1 - 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mac/mtasImplant.mac b/mac/mtasImplant.mac index 615bf95..8683b21 100644 --- a/mac/mtasImplant.mac +++ b/mac/mtasImplant.mac @@ -118,7 +118,7 @@ #/nDet/source/type alpha 5 /nDet/source/type electron 0.1 -/nDet/source/spot 0.1 #half-width for beam +/nDet/source/spot 10 #half-width for beam /nDet/source/shape circle #/nDet/source/beam 137Cs #/nDet/source/beam gamma 0.03 diff --git a/source/centerOfMass.cc b/source/centerOfMass.cc index 586143b..6fb430d 100644 --- a/source/centerOfMass.cc +++ b/source/centerOfMass.cc @@ -91,7 +91,7 @@ double centerOfMass::getSipmY() const { for(int i=0;i(Nrow, 100)); countMatrix.push_back(std::vector(Nrow, 0)); diff --git a/source/nDetRunAction.cc b/source/nDetRunAction.cc index 9ad37b0..08ad882 100644 --- a/source/nDetRunAction.cc +++ b/source/nDetRunAction.cc @@ -554,7 +554,6 @@ bool nDetRunAction::processImplant(nDetImplant* imp){ // 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]); - // std::cout<<"!! Checking Logic :"<getSipmX(); debugData.reconDetComY[0] = cmI->getSipmY(); From 1ed31f1f4c74f1605a16a37f4eae3639a9e31584 Mon Sep 17 00:00:00 2001 From: icox2 Date: Fri, 12 Aug 2022 16:08:19 -0400 Subject: [PATCH 16/17] Fully working Sipm array logic --- mac/mtasImplant.mac | 2 +- source/centerOfMass.cc | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/mac/mtasImplant.mac b/mac/mtasImplant.mac index 8683b21..017c381 100644 --- a/mac/mtasImplant.mac +++ b/mac/mtasImplant.mac @@ -140,4 +140,4 @@ # RUN CONTROL # ############### -/run/beamOn 10000 +/run/beamOn 10 diff --git a/source/centerOfMass.cc b/source/centerOfMass.cc index 6fb430d..bdbc851 100644 --- a/source/centerOfMass.cc +++ b/source/centerOfMass.cc @@ -77,8 +77,8 @@ double centerOfMass::getReconstructedY() const { double centerOfMass::getSipmX() const { double total = 0,x=0; - for(int i=0;i(Nrow, 0)); } } From fea8a6e59175b1eead736d256d98ba2d15117580 Mon Sep 17 00:00:00 2001 From: icox2 Date: Wed, 23 Nov 2022 13:48:05 -0500 Subject: [PATCH 17/17] added LaBr3 dets and maybe more --- include/nDetConstruction.hh | 2 + include/nDetDetectorTypes.hh | 38 +++++++ include/nDetMaterials.hh | 1 + include/nDetParticleSource.hh | 2 +- mac/alphatest.mac | 114 ++++++++++++++++++++ mac/cebrtest.mac | 137 ++++++++++++++++++++++++ mac/cylinder.mac | 75 ++++++++++++++ mac/hagrid.mac | 85 +++++++++++++++ mac/ionTest.mac | 144 ++++++++++++++++++++++++++ mac/mtasImplant.mac | 2 +- mac/pspmt.mac | 27 ++--- mac/ribf168.mac | 112 ++++++++++++++++++++ mac/thintest.mac | 114 ++++++++++++++++++++ source/centerOfMass.cc | 2 +- source/nDetConstruction.cc | 52 +++++++++- source/nDetConstructionMessenger.cc | 2 +- source/nDetDetector.cc | 9 +- source/nDetDetectorTypes.cc | 63 ++++++++++- source/nDetMaterials.cc | 65 +++++++++--- source/nDetParticleSource.cc | 24 +++-- source/nDetParticleSourceMessenger.cc | 11 +- 21 files changed, 1026 insertions(+), 55 deletions(-) create mode 100644 mac/alphatest.mac create mode 100644 mac/cebrtest.mac create mode 100644 mac/cylinder.mac create mode 100644 mac/hagrid.mac create mode 100644 mac/ionTest.mac create mode 100644 mac/ribf168.mac create mode 100644 mac/thintest.mac diff --git a/include/nDetConstruction.hh b/include/nDetConstruction.hh index fbee71e..4be2e0e 100644 --- a/include/nDetConstruction.hh +++ b/include/nDetConstruction.hh @@ -181,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) */ diff --git a/include/nDetDetectorTypes.hh b/include/nDetDetectorTypes.hh index 8d30889..3662b1f 100644 --- a/include/nDetDetectorTypes.hh +++ b/include/nDetDetectorTypes.hh @@ -217,6 +217,44 @@ public: 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/nDetMaterials.hh b/include/nDetMaterials.hh index 59dad9b..c24bb8f 100644 --- a/include/nDetMaterials.hh +++ b/include/nDetMaterials.hh @@ -80,6 +80,7 @@ class nDetMaterials{ 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 diff --git a/include/nDetParticleSource.hh b/include/nDetParticleSource.hh index df5219f..4a58c04 100644 --- a/include/nDetParticleSource.hh +++ b/include/nDetParticleSource.hh @@ -204,7 +204,7 @@ class nDetParticleSource : public G4GeneralParticleSource { /** Set a beam of mono-energetic ions * @param energy_ Energy of the beam (in MeV) */ - void SetIonBeam(const double &energy_); + 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 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/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 index 017c381..8683b21 100644 --- a/mac/mtasImplant.mac +++ b/mac/mtasImplant.mac @@ -140,4 +140,4 @@ # RUN CONTROL # ############### -/run/beamOn 10 +/run/beamOn 10000 diff --git a/mac/pspmt.mac b/mac/pspmt.mac index 8730764..fa26752 100644 --- a/mac/pspmt.mac +++ b/mac/pspmt.mac @@ -34,22 +34,17 @@ # DETECTOR SETUP # ################## -# NEXT 2x2x10 in^3 -/nDet/implant/setDetectorLength 1.2 -/nDet/implant/setDetectorWidth 5.08 -/nDet/implant/setDetectorThickness 50.8 +# 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 24 -/nDet/implant/setNumRows 24 +/nDet/implant/setNumColumns 8 +/nDet/implant/setNumRows 8 /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 @@ -69,7 +64,7 @@ /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 +#/nDet/implant/setSegmentedLightGuide 24 24 5 50.8 50.8 45 45 G4_Pyrex_Glass # Update the detector. @@ -117,8 +112,8 @@ #/nDet/source/type alpha 5 /nDet/source/type 90Sr -/nDet/source/spot 5 #half-width for beam -/nDet/source/shape circle +#/nDet/source/spot 5 #half-width for beam +#/nDet/source/shape circle #/nDet/source/beam 137Cs #/nDet/source/beam gamma 0.03 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/centerOfMass.cc b/source/centerOfMass.cc index bdbc851..abc855d 100644 --- a/source/centerOfMass.cc +++ b/source/centerOfMass.cc @@ -147,7 +147,7 @@ bool centerOfMass::loadSpectralResponse(const char *fname){ } bool centerOfMass::loadGainMatrix(const char *fname){ - if(gainMatrix.empty() || Ncol*Nrow == 0) {std::cout<<"Gain Matrix Empty"< \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); @@ -409,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_); } diff --git a/source/nDetConstructionMessenger.cc b/source/nDetConstructionMessenger.cc index cc736e2..19acaea 100644 --- a/source/nDetConstructionMessenger.cc +++ b/source/nDetConstructionMessenger.cc @@ -326,7 +326,7 @@ void nDetConstructionMessenger::SetNewChildValue(G4UIcommand* command, G4String fDetector->ClearGeometry(); } else if(index == 26){ - fDetector->AddDetectorArray(newValue); + fDetector->AddImplantArray(newValue); } else if(index == 27){ fDetector->PrintAllDetectors(); diff --git a/source/nDetDetector.cc b/source/nDetDetector.cc index 114eaa6..3b158d4 100644 --- a/source/nDetDetector.cc +++ b/source/nDetDetector.cc @@ -717,12 +717,13 @@ G4LogicalVolume *nDetImplant::constructAssembly(){ 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*(2*fGreaseThickness+fWindowThickness+fSensitiveThickness+dzThick); - std::cout<<"z thickness "<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++){ @@ -733,7 +734,7 @@ G4LogicalVolume *nDetImplant::constructAssembly(){ } assemblyWidth = std::max(assemblyWidth, (*iter)->getSizeX()); assemblyHeight = std::max(assemblyHeight, (*iter)->getSizeY()); - assemblyLength += 2*(*iter)->getSizeZ(); + assemblyLength += (*iter)->getSizeZ(); } // Build the assembly box diff --git a/source/nDetDetectorTypes.cc b/source/nDetDetectorTypes.cc index 5282865..1288a48 100644 --- a/source/nDetDetectorTypes.cc +++ b/source/nDetDetectorTypes.cc @@ -29,7 +29,10 @@ nDetDetector* nDetDetectorTypes::getDetectorType(const G4String &geom){ nDetImplant* nDetDetectorTypes::getImplantType(const G4String &geom){ nDetImplant *retval = NULL; - retval = new implantType(); + if(geom == "hagrid") + retval = new hagridType(); + else + retval = new implantType(); return retval; } @@ -48,7 +51,10 @@ nDetDetector* nDetDetectorTypes::getDetectorType(const G4String &geom, nDetConst nDetImplant* nDetDetectorTypes::getImplantType(const G4String &geom, nDetConstruction *construction, nDetMaterials *matptr){ nDetImplant *retval = NULL; - retval = new implantType(construction, matptr); + if(geom == "hagrid") + retval = new hagridType(construction, matptr); + else + retval = new implantType(construction, matptr); return retval; } @@ -452,3 +458,56 @@ void implantType::buildDetector(){ 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/nDetMaterials.cc b/source/nDetMaterials.cc index fd55b12..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; @@ -98,6 +100,7 @@ void nDetMaterials::initialize(){ opticalSurfaceList["perfect"] = fPerfectOpSurf; opticalSurfaceList["grease"] = fGreaseOpSurf; opticalSurfaceList["air"] = fAirOpSurf; + opticalSurfaceList["aluminum"] = fAluminumOpSurf; visAttributesList["air"] = visWrapping; //visAttributesList["vacuum"] = &G4VisAttributes::Invisible; @@ -622,6 +625,12 @@ void nDetMaterials::defineMaterials(){ //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; @@ -798,21 +807,44 @@ void nDetMaterials::defineScintillators(){ 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]; + // 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]; - } + // 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, electronYield_YSO, 36)->SetSpline(true); - fYSOMPT->AddProperty("PROTONSCINTILLATIONYIELD", particleEnergy, protonYield_YSO, 36)->SetSpline(true); - fYSOMPT->AddProperty("IONSCINTILLATIONYIELD", particleEnergy, ionYield_YSO, 36)->SetSpline(true); + 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); @@ -837,16 +869,15 @@ void nDetMaterials::defineScintillators(){ 0.105, 0.028, 0.004, 0.000}; G4double photonEnergy_LaBr3_2[2] = {2.004*eV, 3.191*eV}; - G4double RefIndex_LaBr3[2] = {1.580, 1.580}; - G4double Absorption_LaBr3[2] = {400*cm, 400*cm}; + 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", 0.64*17400/MeV); // 64% of Anthracene - fLaBr3MPT->AddConstProperty("SCINTILLATIONYIELD", 10000/MeV); // Scintillation efficiency as per Eljen specs + fLaBr3MPT->AddConstProperty("SCINTILLATIONYIELD", 630000/MeV); fLaBr3MPT->AddConstProperty("RESOLUTIONSCALE", 1.0); // Intrinsic resolution //fLaBr3MPT->AddConstProperty("RISETIMECONSTANT", 0.9*ns); Geant4 10.1 TODO @@ -873,14 +904,14 @@ void nDetMaterials::defineScintillators(){ 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); + // 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); + // fLaBr3MPT->AddProperty("IONSCINTILLATIONYIELD", particleEnergy_LaBr3, ionYield_LaBr3, 36)->SetSpline(true); fLaBr3->SetMaterialPropertiesTable(fLaBr3MPT); diff --git a/source/nDetParticleSource.cc b/source/nDetParticleSource.cc index e9c678d..ce84977 100644 --- a/source/nDetParticleSource.cc +++ b/source/nDetParticleSource.cc @@ -17,7 +17,8 @@ #include "G4Neutron.hh" #include "G4Gamma.hh" #include "G4Alpha.hh" -#include "G4Ions.hh" +#include "G4GenericIon.hh" +#include "G4IonTable.hh" #include "G4OpticalPhoton.hh" #include "G4Electron.hh" #include "Randomize.hh" @@ -97,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); } } @@ -134,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") @@ -154,8 +163,8 @@ bool nDetParticleSource::SetSourceType(const G4String &str){ SetNeutronBeam(beamEnergy); else if(typeName == "alpha") SetAlphaBeam(beamEnergy); - /*else if(typeName == "ion") - SetIonBeam(beamEnergy);*/ + else if(typeName == "ion") + SetIonBeam(beamEnergy,mass,charge); else if(typeName == "gamma") SetGammaRayBeam(beamEnergy); else if(typeName == "laser"){ @@ -324,12 +333,13 @@ void nDetParticleSource::SetAlphaBeam(const double &energy_){ SetBeamEnergy(energy_*MeV); } -/*void nDetParticleSource::SetIonBeam(const double &energy_){ - std::cout<<"Ion Beam"< "); - addCommand(new G4UIcmdWithAString("/nDet/source/ion", this)); // type of source (252Cf, 137Cs, etc) - addGuidance("Set a pre-defined isotropic ion particle source"); - addGuidance("108Xe for Xenon-108 beam for implantation"); + 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){ @@ -124,6 +127,6 @@ void nDetParticleSourceMessenger::SetNewChildValue(G4UIcommand* command, G4Strin fAction->SetBeamEnergySigma(newValue); } else if(index==16){ - //fAction->SetIonBeam(newValue); + fAction->SetSourcePosition(G4UIcommand::ConvertTo3Vector(newValue)); } }