From 31f528dc2d9e1152ba3dc60071369cdd0fc8749c Mon Sep 17 00:00:00 2001 From: Xythere <xytherex@gmail.com> Date: Fri, 13 Dec 2024 14:48:10 +0100 Subject: [PATCH] inital commit --- NPLib/Detectors/CeBr3/CMakeLists.txt | 6 + NPLib/Detectors/CeBr3/TCeBr3Data.cxx | 79 ++++ NPLib/Detectors/CeBr3/TCeBr3Data.h | 104 +++++ NPLib/Detectors/CeBr3/TCeBr3Physics.cxx | 344 +++++++++++++++ NPLib/Detectors/CeBr3/TCeBr3Physics.h | 180 ++++++++ NPLib/Detectors/CeBr3/TCeBr3Spectra.cxx | 174 ++++++++ NPLib/Detectors/CeBr3/TCeBr3Spectra.h | 62 +++ NPLib/Detectors/GeLi/CMakeLists.txt | 6 + NPLib/Detectors/GeLi/TGeLiData.cxx | 79 ++++ NPLib/Detectors/GeLi/TGeLiData.h | 104 +++++ NPLib/Detectors/GeLi/TGeLiPhysics.cxx | 344 +++++++++++++++ NPLib/Detectors/GeLi/TGeLiPhysics.h | 180 ++++++++ NPLib/Detectors/GeLi/TGeLiSpectra.cxx | 174 ++++++++ NPLib/Detectors/GeLi/TGeLiSpectra.h | 62 +++ NPLib/Detectors/quadranMSQ25/CMakeLists.txt | 6 + .../quadranMSQ25/TquadranMSQ25Data.cxx | 82 ++++ .../quadranMSQ25/TquadranMSQ25Data.h | 75 ++++ .../quadranMSQ25/TquadranMSQ25Physics.cxx | 310 ++++++++++++++ .../quadranMSQ25/TquadranMSQ25Physics.h | 132 ++++++ NPSimulation/Core/MaterialManager.cc | 22 + NPSimulation/Detectors/AnnularS4/AnnularS4.cc | 319 ++++++++++++++ NPSimulation/Detectors/AnnularS4/AnnularS4.hh | 150 +++++++ .../Detectors/AnnularS4/CMakeLists.txt | 2 + NPSimulation/Detectors/CeBr3/CMakeLists.txt | 2 + NPSimulation/Detectors/CeBr3/CeBr3.cc | 292 +++++++++++++ NPSimulation/Detectors/CeBr3/CeBr3.hh | 117 +++++ NPSimulation/Detectors/GeLi/CMakeLists.txt | 2 + NPSimulation/Detectors/GeLi/GeLi.cc | 292 +++++++++++++ NPSimulation/Detectors/GeLi/GeLi.hh | 117 +++++ .../Detectors/quadranMSQ25/CMakeLists.txt | 2 + .../Detectors/quadranMSQ25/quadranMSQ25.cc | 399 ++++++++++++++++++ .../Detectors/quadranMSQ25/quadranMSQ25.hh | 170 ++++++++ .../EventGenerator/EventGeneratorIsotropic.cc | 3 +- 33 files changed, 4391 insertions(+), 1 deletion(-) create mode 100644 NPLib/Detectors/CeBr3/CMakeLists.txt create mode 100644 NPLib/Detectors/CeBr3/TCeBr3Data.cxx create mode 100644 NPLib/Detectors/CeBr3/TCeBr3Data.h create mode 100644 NPLib/Detectors/CeBr3/TCeBr3Physics.cxx create mode 100644 NPLib/Detectors/CeBr3/TCeBr3Physics.h create mode 100644 NPLib/Detectors/CeBr3/TCeBr3Spectra.cxx create mode 100644 NPLib/Detectors/CeBr3/TCeBr3Spectra.h create mode 100644 NPLib/Detectors/GeLi/CMakeLists.txt create mode 100644 NPLib/Detectors/GeLi/TGeLiData.cxx create mode 100644 NPLib/Detectors/GeLi/TGeLiData.h create mode 100644 NPLib/Detectors/GeLi/TGeLiPhysics.cxx create mode 100644 NPLib/Detectors/GeLi/TGeLiPhysics.h create mode 100644 NPLib/Detectors/GeLi/TGeLiSpectra.cxx create mode 100644 NPLib/Detectors/GeLi/TGeLiSpectra.h create mode 100644 NPLib/Detectors/quadranMSQ25/CMakeLists.txt create mode 100644 NPLib/Detectors/quadranMSQ25/TquadranMSQ25Data.cxx create mode 100644 NPLib/Detectors/quadranMSQ25/TquadranMSQ25Data.h create mode 100644 NPLib/Detectors/quadranMSQ25/TquadranMSQ25Physics.cxx create mode 100644 NPLib/Detectors/quadranMSQ25/TquadranMSQ25Physics.h create mode 100644 NPSimulation/Detectors/AnnularS4/AnnularS4.cc create mode 100644 NPSimulation/Detectors/AnnularS4/AnnularS4.hh create mode 100644 NPSimulation/Detectors/AnnularS4/CMakeLists.txt create mode 100644 NPSimulation/Detectors/CeBr3/CMakeLists.txt create mode 100644 NPSimulation/Detectors/CeBr3/CeBr3.cc create mode 100644 NPSimulation/Detectors/CeBr3/CeBr3.hh create mode 100644 NPSimulation/Detectors/GeLi/CMakeLists.txt create mode 100644 NPSimulation/Detectors/GeLi/GeLi.cc create mode 100644 NPSimulation/Detectors/GeLi/GeLi.hh create mode 100644 NPSimulation/Detectors/quadranMSQ25/CMakeLists.txt create mode 100644 NPSimulation/Detectors/quadranMSQ25/quadranMSQ25.cc create mode 100644 NPSimulation/Detectors/quadranMSQ25/quadranMSQ25.hh diff --git a/NPLib/Detectors/CeBr3/CMakeLists.txt b/NPLib/Detectors/CeBr3/CMakeLists.txt new file mode 100644 index 000000000..6f0c35921 --- /dev/null +++ b/NPLib/Detectors/CeBr3/CMakeLists.txt @@ -0,0 +1,6 @@ +add_custom_command(OUTPUT TCeBr3PhysicsDict.cxx COMMAND ../../scripts/build_dict.sh TCeBr3Physics.h TCeBr3PhysicsDict.cxx TCeBr3Physics.rootmap libNPCeBr3.dylib DEPENDS TCeBr3Physics.h) +add_custom_command(OUTPUT TCeBr3DataDict.cxx COMMAND ../../scripts/build_dict.sh TCeBr3Data.h TCeBr3DataDict.cxx TCeBr3Data.rootmap libNPCeBr3.dylib DEPENDS TCeBr3Data.h) +add_library(NPCeBr3 SHARED TCeBr3Spectra.cxx TCeBr3Data.cxx TCeBr3Physics.cxx TCeBr3DataDict.cxx TCeBr3PhysicsDict.cxx ) +target_link_libraries(NPCeBr3 ${ROOT_LIBRARIES} NPCore) +install(FILES TCeBr3Data.h TCeBr3Physics.h TCeBr3Spectra.h DESTINATION ${CMAKE_INCLUDE_OUTPUT_DIRECTORY}) + diff --git a/NPLib/Detectors/CeBr3/TCeBr3Data.cxx b/NPLib/Detectors/CeBr3/TCeBr3Data.cxx new file mode 100644 index 000000000..599a8f28d --- /dev/null +++ b/NPLib/Detectors/CeBr3/TCeBr3Data.cxx @@ -0,0 +1,79 @@ +/***************************************************************************** + * Copyright (C) 2009-2023 this file is part of the NPTool Project * + * * + * For the licensing terms see $NPTOOL/Licence/NPTool_Licence * + * For the list of contributors see $NPTOOL/Licence/Contributors * + *****************************************************************************/ + +/***************************************************************************** + * Original Author: Leo Plagnol contact address: plagnol@ijclab.in2p3.fr * + * * + * Creation Date : December 2023 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class hold CeBr3 Raw data * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + * * + *****************************************************************************/ +#include "TCeBr3Data.h" + +#include <iostream> +#include <fstream> +#include <sstream> +#include <string> +using namespace std; + +ClassImp(TCeBr3Data) + + +////////////////////////////////////////////////////////////////////// +TCeBr3Data::TCeBr3Data() { +} + + + +////////////////////////////////////////////////////////////////////// +TCeBr3Data::~TCeBr3Data() { +} + + + +////////////////////////////////////////////////////////////////////// +void TCeBr3Data::Clear() { + // Energy + fCeBr3_E_DetectorNbr.clear(); + fCeBr3_Energy.clear(); + // Time + fCeBr3_T_DetectorNbr.clear(); + fCeBr3_Time.clear(); +} + + + +////////////////////////////////////////////////////////////////////// +void TCeBr3Data::Dump() const { + // This method is very useful for debuging and worth the dev. + cout << "XXXXXXXXXXXXXXXXXXXXXXXX New Event [TCeBr3Data::Dump()] XXXXXXXXXXXXXXXXX" << endl; + + // Energy + size_t mysize = fCeBr3_E_DetectorNbr.size(); + cout << "CeBr3_E_Mult: " << mysize << endl; + + for (size_t i = 0 ; i < mysize ; i++){ + cout << "DetNbr: " << fCeBr3_E_DetectorNbr[i] + << " Energy: " << fCeBr3_Energy[i]; + } + + // Time + mysize = fCeBr3_T_DetectorNbr.size(); + cout << "CeBr3_T_Mult: " << mysize << endl; + + for (size_t i = 0 ; i < mysize ; i++){ + cout << "DetNbr: " << fCeBr3_T_DetectorNbr[i] + << " Time: " << fCeBr3_Time[i]; + } +} diff --git a/NPLib/Detectors/CeBr3/TCeBr3Data.h b/NPLib/Detectors/CeBr3/TCeBr3Data.h new file mode 100644 index 000000000..427f82b78 --- /dev/null +++ b/NPLib/Detectors/CeBr3/TCeBr3Data.h @@ -0,0 +1,104 @@ +#ifndef __CeBr3DATA__ +#define __CeBr3DATA__ +/***************************************************************************** + * Copyright (C) 2009-2023 this file is part of the NPTool Project * + * * + * For the licensing terms see $NPTOOL/Licence/NPTool_Licence * + * For the list of contributors see $NPTOOL/Licence/Contributors * + *****************************************************************************/ + +/***************************************************************************** + * Original Author: Leo Plagnol contact address: plagnol@ijclab.in2p3.fr * + * * + * Creation Date : December 2023 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class hold CeBr3 Raw data * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + * * + *****************************************************************************/ + +// STL +#include <vector> +using namespace std; + +// ROOT +#include "TObject.h" + +class TCeBr3Data : public TObject { + ////////////////////////////////////////////////////////////// + // data members are hold into vectors in order + // to allow multiplicity treatment + private: + // Energy + vector<UShort_t> fCeBr3_E_DetectorNbr; + vector<Double_t> fCeBr3_Energy; + + // Time + vector<UShort_t> fCeBr3_T_DetectorNbr; + vector<Double_t> fCeBr3_Time; + + + ////////////////////////////////////////////////////////////// + // Constructor and destructor + public: + TCeBr3Data(); + ~TCeBr3Data(); + + + ////////////////////////////////////////////////////////////// + // Inherited from TObject and overriden to avoid warnings + public: + void Clear(); + void Clear(const Option_t*) {}; + void Dump() const; + + + ////////////////////////////////////////////////////////////// + // Getters and Setters + // Prefer inline declaration to avoid unnecessary called of + // frequently used methods + // add //! to avoid ROOT creating dictionnary for the methods + public: + ////////////////////// SETTERS //////////////////////// + // Energy + inline void SetEnergy(const UShort_t& DetNbr,const Double_t& Energy){ + fCeBr3_E_DetectorNbr.push_back(DetNbr); + fCeBr3_Energy.push_back(Energy); + };//! + + // Time + inline void SetTime(const UShort_t& DetNbr,const Double_t& Time) { + fCeBr3_T_DetectorNbr.push_back(DetNbr); + fCeBr3_Time.push_back(Time); + };//! + + + ////////////////////// GETTERS //////////////////////// + // Energy + inline UShort_t GetMultEnergy() const + {return fCeBr3_E_DetectorNbr.size();} + inline UShort_t GetE_DetectorNbr(const unsigned int &i) const + {return fCeBr3_E_DetectorNbr[i];}//! + inline Double_t Get_Energy(const unsigned int &i) const + {return fCeBr3_Energy[i];}//! + + // Time + inline UShort_t GetMultTime() const + {return fCeBr3_T_DetectorNbr.size();} + inline UShort_t GetT_DetectorNbr(const unsigned int &i) const + {return fCeBr3_T_DetectorNbr[i];}//! + inline Double_t Get_Time(const unsigned int &i) const + {return fCeBr3_Time[i];}//! + + + ////////////////////////////////////////////////////////////// + // Required for ROOT dictionnary + ClassDef(TCeBr3Data,1) // CeBr3Data structure +}; + +#endif diff --git a/NPLib/Detectors/CeBr3/TCeBr3Physics.cxx b/NPLib/Detectors/CeBr3/TCeBr3Physics.cxx new file mode 100644 index 000000000..213539aa6 --- /dev/null +++ b/NPLib/Detectors/CeBr3/TCeBr3Physics.cxx @@ -0,0 +1,344 @@ +/***************************************************************************** + * Copyright (C) 2009-2023 this file is part of the NPTool Project * + * * + * For the licensing terms see $NPTOOL/Licence/NPTool_Licence * + * For the list of contributors see $NPTOOL/Licence/Contributors * + *****************************************************************************/ + +/***************************************************************************** + * Original Author: Leo Plagnol contact address: plagnol@ijclab.in2p3.fr * + * * + * Creation Date : December 2023 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class hold CeBr3 Treated data * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + * * + *****************************************************************************/ + +#include "TCeBr3Physics.h" + +// STL +#include <sstream> +#include <iostream> +#include <cmath> +#include <stdlib.h> +#include <limits> +using namespace std; + +// NPL +#include "RootInput.h" +#include "RootOutput.h" +#include "NPDetectorFactory.h" +#include "NPOptionManager.h" + +// ROOT +#include "TChain.h" + +ClassImp(TCeBr3Physics) + + +/////////////////////////////////////////////////////////////////////////// +TCeBr3Physics::TCeBr3Physics() + : m_EventData(new TCeBr3Data), + m_PreTreatedData(new TCeBr3Data), + m_EventPhysics(this), + m_Spectra(0), + m_E_RAW_Threshold(0), // adc channels + m_E_Threshold(0), // MeV + m_NumberOfDetectors(0) { +} + +/////////////////////////////////////////////////////////////////////////// +/// A usefull method to bundle all operation to add a detector +void TCeBr3Physics::AddDetector(TVector3 , string ){ + // In That simple case nothing is done + // Typically for more complex detector one would calculate the relevant + // positions (stripped silicon) or angles (gamma array) + m_NumberOfDetectors++; +} + +/////////////////////////////////////////////////////////////////////////// +void TCeBr3Physics::AddDetector(double R, double Theta, double Phi, string shape){ + // Compute the TVector3 corresponding + TVector3 Pos(R*sin(Theta)*cos(Phi),R*sin(Theta)*sin(Phi),R*cos(Theta)); + // Call the cartesian method + AddDetector(Pos,shape); +} + +/////////////////////////////////////////////////////////////////////////// +void TCeBr3Physics::BuildSimplePhysicalEvent() { + BuildPhysicalEvent(); +} + + + +/////////////////////////////////////////////////////////////////////////// +void TCeBr3Physics::BuildPhysicalEvent() { + // apply thresholds and calibration + PreTreat(); + + // match energy and time together + unsigned int mysizeE = m_PreTreatedData->GetMultEnergy(); + unsigned int mysizeT = m_PreTreatedData->GetMultTime(); + for (UShort_t e = 0; e < mysizeE ; e++) { + for (UShort_t t = 0; t < mysizeT ; t++) { + if (m_PreTreatedData->GetE_DetectorNbr(e) == m_PreTreatedData->GetT_DetectorNbr(t)) { + DetectorNumber.push_back(m_PreTreatedData->GetE_DetectorNbr(e)); + Energy.push_back(m_PreTreatedData->Get_Energy(e)); + Time.push_back(m_PreTreatedData->Get_Time(t)); + } + } + } +} + +/////////////////////////////////////////////////////////////////////////// +void TCeBr3Physics::PreTreat() { + // This method typically applies thresholds and calibrations + // Might test for disabled channels for more complex detector + + // clear pre-treated object + ClearPreTreatedData(); + + // instantiate CalibrationManager + static CalibrationManager* Cal = CalibrationManager::getInstance(); + + // Energy + unsigned int mysize = m_EventData->GetMultEnergy(); + for (UShort_t i = 0; i < mysize ; ++i) { + if (m_EventData->Get_Energy(i) > m_E_RAW_Threshold) { + Double_t Energy = Cal->ApplyCalibration("CeBr3/ENERGY"+NPL::itoa(m_EventData->GetE_DetectorNbr(i)),m_EventData->Get_Energy(i)); + if (Energy > m_E_Threshold) { + m_PreTreatedData->SetEnergy(m_EventData->GetE_DetectorNbr(i), Energy); + } + } + } + + // Time + mysize = m_EventData->GetMultTime(); + for (UShort_t i = 0; i < mysize; ++i) { + Double_t Time= Cal->ApplyCalibration("CeBr3/TIME"+NPL::itoa(m_EventData->GetT_DetectorNbr(i)),m_EventData->Get_Time(i)); + m_PreTreatedData->SetTime(m_EventData->GetT_DetectorNbr(i), Time); + } +} + + + +/////////////////////////////////////////////////////////////////////////// +void TCeBr3Physics::ReadAnalysisConfig() { + bool ReadingStatus = false; + + // path to file + string FileName = "./configs/ConfigCeBr3.dat"; + + // open analysis config file + ifstream AnalysisConfigFile; + AnalysisConfigFile.open(FileName.c_str()); + + if (!AnalysisConfigFile.is_open()) { + cout << " No ConfigCeBr3.dat found: Default parameter loaded for Analayis " << FileName << endl; + return; + } + cout << " Loading user parameter for Analysis from ConfigCeBr3.dat " << endl; + + // Save it in a TAsciiFile + TAsciiFile* asciiConfig = RootOutput::getInstance()->GetAsciiFileAnalysisConfig(); + asciiConfig->AppendLine("%%% ConfigCeBr3.dat %%%"); + asciiConfig->Append(FileName.c_str()); + asciiConfig->AppendLine(""); + // read analysis config file + string LineBuffer,DataBuffer,whatToDo; + while (!AnalysisConfigFile.eof()) { + // Pick-up next line + getline(AnalysisConfigFile, LineBuffer); + + // search for "header" + string name = "ConfigCeBr3"; + if (LineBuffer.compare(0, name.length(), name) == 0) + ReadingStatus = true; + + // loop on tokens and data + while (ReadingStatus ) { + whatToDo=""; + AnalysisConfigFile >> whatToDo; + + // Search for comment symbol (%) + if (whatToDo.compare(0, 1, "%") == 0) { + AnalysisConfigFile.ignore(numeric_limits<streamsize>::max(), '\n' ); + } + + else if (whatToDo=="E_RAW_THRESHOLD") { + AnalysisConfigFile >> DataBuffer; + m_E_RAW_Threshold = atof(DataBuffer.c_str()); + cout << whatToDo << " " << m_E_RAW_Threshold << endl; + } + + else if (whatToDo=="E_THRESHOLD") { + AnalysisConfigFile >> DataBuffer; + m_E_Threshold = atof(DataBuffer.c_str()); + cout << whatToDo << " " << m_E_Threshold << endl; + } + + else { + ReadingStatus = false; + } + } + } +} + + + +/////////////////////////////////////////////////////////////////////////// +void TCeBr3Physics::Clear() { + DetectorNumber.clear(); + Energy.clear(); + Time.clear(); +} + + + +/////////////////////////////////////////////////////////////////////////// +void TCeBr3Physics::ReadConfiguration(NPL::InputParser parser) { + vector<NPL::InputBlock*> blocks = parser.GetAllBlocksWithToken("CeBr3"); + if(NPOptionManager::getInstance()->GetVerboseLevel()) + cout << "//// " << blocks.size() << " detectors found " << endl; + + vector<string> cart = {"POS","Shape"}; + vector<string> sphe = {"R","Theta","Phi","Shape"}; + + for(unsigned int i = 0 ; i < blocks.size() ; i++){ + if(blocks[i]->HasTokenList(cart)){ + if(NPOptionManager::getInstance()->GetVerboseLevel()) + cout << endl << "//// CeBr3 " << i+1 << endl; + + TVector3 Pos = blocks[i]->GetTVector3("POS","mm"); + string Shape = blocks[i]->GetString("Shape"); + AddDetector(Pos,Shape); + } + else if(blocks[i]->HasTokenList(sphe)){ + if(NPOptionManager::getInstance()->GetVerboseLevel()) + cout << endl << "//// CeBr3 " << i+1 << endl; + double R = blocks[i]->GetDouble("R","mm"); + double Theta = blocks[i]->GetDouble("Theta","deg"); + double Phi = blocks[i]->GetDouble("Phi","deg"); + string Shape = blocks[i]->GetString("Shape"); + AddDetector(R,Theta,Phi,Shape); + } + else{ + cout << "ERROR: check your input file formatting " << endl; + exit(1); + } + } +} + +/////////////////////////////////////////////////////////////////////////// +void TCeBr3Physics::InitSpectra() { + m_Spectra = new TCeBr3Spectra(m_NumberOfDetectors); +} + + + +/////////////////////////////////////////////////////////////////////////// +void TCeBr3Physics::FillSpectra() { + m_Spectra -> FillRawSpectra(m_EventData); + m_Spectra -> FillPreTreatedSpectra(m_PreTreatedData); + m_Spectra -> FillPhysicsSpectra(m_EventPhysics); +} + + + +/////////////////////////////////////////////////////////////////////////// +void TCeBr3Physics::CheckSpectra() { + m_Spectra->CheckSpectra(); +} + + + +/////////////////////////////////////////////////////////////////////////// +void TCeBr3Physics::ClearSpectra() { + // To be done +} + + + +/////////////////////////////////////////////////////////////////////////// +map< string , TH1*> TCeBr3Physics::GetSpectra() { + if(m_Spectra) + return m_Spectra->GetMapHisto(); + else{ + map< string , TH1*> empty; + return empty; + } +} + +/////////////////////////////////////////////////////////////////////////// +void TCeBr3Physics::WriteSpectra() { + m_Spectra->WriteSpectra(); +} + + + +/////////////////////////////////////////////////////////////////////////// +void TCeBr3Physics::AddParameterToCalibrationManager() { + CalibrationManager* Cal = CalibrationManager::getInstance(); + for (int i = 0; i < m_NumberOfDetectors; ++i) { + Cal->AddParameter("CeBr3", "D"+ NPL::itoa(i+1)+"_ENERGY","CeBr3_D"+ NPL::itoa(i+1)+"_ENERGY"); + Cal->AddParameter("CeBr3", "D"+ NPL::itoa(i+1)+"_TIME","CeBr3_D"+ NPL::itoa(i+1)+"_TIME"); + } +} + + + +/////////////////////////////////////////////////////////////////////////// +void TCeBr3Physics::InitializeRootInputRaw() { + TChain* inputChain = RootInput::getInstance()->GetChain(); + inputChain->SetBranchStatus("CeBr3", true ); + inputChain->SetBranchAddress("CeBr3", &m_EventData ); +} + + + +/////////////////////////////////////////////////////////////////////////// +void TCeBr3Physics::InitializeRootInputPhysics() { + TChain* inputChain = RootInput::getInstance()->GetChain(); + inputChain->SetBranchAddress("CeBr3", &m_EventPhysics); +} + + + +/////////////////////////////////////////////////////////////////////////// +void TCeBr3Physics::InitializeRootOutput() { + TTree* outputTree = RootOutput::getInstance()->GetTree(); + outputTree->Branch("CeBr3", "TCeBr3Physics", &m_EventPhysics); +} + + + +//////////////////////////////////////////////////////////////////////////////// +// Construct Method to be pass to the DetectorFactory // +//////////////////////////////////////////////////////////////////////////////// +NPL::VDetector* TCeBr3Physics::Construct() { + return (NPL::VDetector*) new TCeBr3Physics(); +} + + + +//////////////////////////////////////////////////////////////////////////////// +// Registering the construct method to the factory // +//////////////////////////////////////////////////////////////////////////////// +extern "C"{ +class proxy_CeBr3{ + public: + proxy_CeBr3(){ + NPL::DetectorFactory::getInstance()->AddToken("CeBr3","CeBr3"); + NPL::DetectorFactory::getInstance()->AddDetector("CeBr3",TCeBr3Physics::Construct); + } +}; + +proxy_CeBr3 p_CeBr3; +} + diff --git a/NPLib/Detectors/CeBr3/TCeBr3Physics.h b/NPLib/Detectors/CeBr3/TCeBr3Physics.h new file mode 100644 index 000000000..46427ce60 --- /dev/null +++ b/NPLib/Detectors/CeBr3/TCeBr3Physics.h @@ -0,0 +1,180 @@ +#ifndef TCeBr3PHYSICS_H +#define TCeBr3PHYSICS_H +/***************************************************************************** + * Copyright (C) 2009-2023 this file is part of the NPTool Project * + * * + * For the licensing terms see $NPTOOL/Licence/NPTool_Licence * + * For the list of contributors see $NPTOOL/Licence/Contributors * + *****************************************************************************/ + +/***************************************************************************** + * Original Author: Leo Plagnol contact address: plagnol@ijclab.in2p3.fr * + * * + * Creation Date : December 2023 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class hold CeBr3 Treated data * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + * * + *****************************************************************************/ + +// C++ headers +#include <vector> +#include <map> +#include <string> +using namespace std; + +// ROOT headers +#include "TObject.h" +#include "TH1.h" +#include "TVector3.h" +// NPTool headers +#include "TCeBr3Data.h" +#include "TCeBr3Spectra.h" +#include "NPCalibrationManager.h" +#include "NPVDetector.h" +#include "NPInputParser.h" +// forward declaration +class TCeBr3Spectra; + + + +class TCeBr3Physics : public TObject, public NPL::VDetector { + ////////////////////////////////////////////////////////////// + // constructor and destructor + public: + TCeBr3Physics(); + ~TCeBr3Physics() {}; + + + ////////////////////////////////////////////////////////////// + // Inherited from TObject and overriden to avoid warnings + public: + void Clear(); + void Clear(const Option_t*) {}; + + + ////////////////////////////////////////////////////////////// + // data obtained after BuildPhysicalEvent() and stored in + // output ROOT file + public: + vector<int> DetectorNumber; + vector<double> Energy; + vector<double> Time; + + /// A usefull method to bundle all operation to add a detector + void AddDetector(TVector3 POS, string shape); + void AddDetector(double R, double Theta, double Phi, string shape); + + ////////////////////////////////////////////////////////////// + // methods inherited from the VDetector ABC class + public: + // read stream from ConfigFile to pick-up detector parameters + void ReadConfiguration(NPL::InputParser); + + // add parameters to the CalibrationManger + void AddParameterToCalibrationManager(); + + // method called event by event, aiming at extracting the + // physical information from detector + void BuildPhysicalEvent(); + + // same as BuildPhysicalEvent() method but with a simpler + // treatment + void BuildSimplePhysicalEvent(); + + // same as above but for online analysis + void BuildOnlinePhysicalEvent() {BuildPhysicalEvent();}; + + // activate raw data object and branches from input TChain + // in this method mother branches (Detector) AND daughter leaves + // (fDetector_parameter) have to be activated + void InitializeRootInputRaw(); + + // activate physics data object and branches from input TChain + // in this method mother branches (Detector) AND daughter leaves + // (fDetector_parameter) have to be activated + void InitializeRootInputPhysics(); + + // create branches of output ROOT file + void InitializeRootOutput(); + + // clear the raw and physical data objects event by event + void ClearEventPhysics() {Clear();} + void ClearEventData() {m_EventData->Clear();} + + // methods related to the TCeBr3Spectra class + // instantiate the TCeBr3Spectra class and + // declare list of histograms + void InitSpectra(); + + // fill the spectra + void FillSpectra(); + + // used for Online mainly, sanity check for histograms and + // change their color if issues are found, for example + void CheckSpectra(); + + // used for Online only, clear all the spectra + void ClearSpectra(); + + // write spectra to ROOT output file + void WriteSpectra(); + + + ////////////////////////////////////////////////////////////// + // specific methods to CeBr3 array + public: + // remove bad channels, calibrate the data and apply thresholds + void PreTreat(); + + // clear the pre-treated object + void ClearPreTreatedData() {m_PreTreatedData->Clear();} + + // read the user configuration file. If no file is found, load standard one + void ReadAnalysisConfig(); + + // give and external TCeBr3Data object to TCeBr3Physics. + // needed for online analysis for example + void SetRawDataPointer(TCeBr3Data* rawDataPointer) {m_EventData = rawDataPointer;} + + // objects are not written in the TTree + private: + TCeBr3Data* m_EventData; //! + TCeBr3Data* m_PreTreatedData; //! + TCeBr3Physics* m_EventPhysics; //! + + // getters for raw and pre-treated data object + public: + TCeBr3Data* GetRawData() const {return m_EventData;} + TCeBr3Data* GetPreTreatedData() const {return m_PreTreatedData;} + + // parameters used in the analysis + private: + // thresholds + double m_E_RAW_Threshold; //! + double m_E_Threshold; //! + + // number of detectors + private: + int m_NumberOfDetectors; //! + + // spectra class + private: + TCeBr3Spectra* m_Spectra; // ! + + // spectra getter + public: + map<string, TH1*> GetSpectra(); + + // Static constructor to be passed to the Detector Factory + public: + static NPL::VDetector* Construct(); + + ClassDef(TCeBr3Physics,1) // CeBr3Physics structure +}; +#endif diff --git a/NPLib/Detectors/CeBr3/TCeBr3Spectra.cxx b/NPLib/Detectors/CeBr3/TCeBr3Spectra.cxx new file mode 100644 index 000000000..ca54efd20 --- /dev/null +++ b/NPLib/Detectors/CeBr3/TCeBr3Spectra.cxx @@ -0,0 +1,174 @@ +/***************************************************************************** + * Copyright (C) 2009-2023 this file is part of the NPTool Project * + * * + * For the licensing terms see $NPTOOL/Licence/NPTool_Licence * + * For the list of contributors see $NPTOOL/Licence/Contributors * + *****************************************************************************/ + +/***************************************************************************** + * Original Author: Leo Plagnol contact address: plagnol@ijclab.in2p3.fr * + * * + * Creation Date : December 2023 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class hold CeBr3 Spectra * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + * * + *****************************************************************************/ + +// class header +#include "TCeBr3Spectra.h" + +// STL +#include <iostream> +#include <string> +using namespace std; + +// NPTool header +#include "NPOptionManager.h" + + + +//////////////////////////////////////////////////////////////////////////////// +TCeBr3Spectra::TCeBr3Spectra() + : fNumberOfDetectors(0) { + SetName("CeBr3"); +} + + + +//////////////////////////////////////////////////////////////////////////////// +TCeBr3Spectra::TCeBr3Spectra(unsigned int NumberOfDetectors) { + if(NPOptionManager::getInstance()->GetVerboseLevel()>0) + cout << "************************************************" << endl + << "TCeBr3Spectra : Initalizing control spectra for " + << NumberOfDetectors << " Detectors" << endl + << "************************************************" << endl ; + SetName("CeBr3"); + fNumberOfDetectors = NumberOfDetectors; + + InitRawSpectra(); + InitPreTreatedSpectra(); + InitPhysicsSpectra(); +} + + + +//////////////////////////////////////////////////////////////////////////////// +TCeBr3Spectra::~TCeBr3Spectra() { +} + + + +//////////////////////////////////////////////////////////////////////////////// +void TCeBr3Spectra::InitRawSpectra() { + static string name; + for (unsigned int i = 0; i < fNumberOfDetectors; i++) { // loop on number of detectors + // Energy + name = "CeBr3"+NPL::itoa(i+1)+"_ENERGY_RAW"; + AddHisto1D(name, name, 4096, 0, 16384, "CeBr3/RAW"); + // Time + name = "CeBr3"+NPL::itoa(i+1)+"_TIME_RAW"; + AddHisto1D(name, name, 4096, 0, 16384, "CeBr3/RAW"); + } // end loop on number of detectors +} + + + +//////////////////////////////////////////////////////////////////////////////// +void TCeBr3Spectra::InitPreTreatedSpectra() { + static string name; + for (unsigned int i = 0; i < fNumberOfDetectors; i++) { // loop on number of detectors + // Energy + name = "CeBr3"+NPL::itoa(i+1)+"_ENERGY_CAL"; + AddHisto1D(name, name, 500, 0, 25, "CeBr3/CAL"); + // Time + name = "CeBr3"+NPL::itoa(i+1)+"_TIME_CAL"; + AddHisto1D(name, name, 500, 0, 25, "CeBr3/CAL"); + + + } // end loop on number of detectors +} + + + +//////////////////////////////////////////////////////////////////////////////// +void TCeBr3Spectra::InitPhysicsSpectra() { + static string name; + // Kinematic Plot + name = "CeBr3_ENERGY_TIME"; + AddHisto2D(name, name, 500, 0, 500, 500, 0, 50, "CeBr3/PHY"); +} + + + +//////////////////////////////////////////////////////////////////////////////// +void TCeBr3Spectra::FillRawSpectra(TCeBr3Data* RawData) { + static string name; + static string family; + + // Energy + unsigned int sizeE = RawData->GetMultEnergy(); + for (unsigned int i = 0; i < sizeE; i++) { + name = "CeBr3"+NPL::itoa(RawData->GetE_DetectorNbr(i))+"_ENERGY_RAW"; + family = "CeBr3/RAW"; + + FillSpectra(family,name,RawData->Get_Energy(i)); + } + + // Time + unsigned int sizeT = RawData->GetMultTime(); + for (unsigned int i = 0; i < sizeT; i++) { + name = "CeBr3"+NPL::itoa(RawData->GetT_DetectorNbr(i))+"_TIME_RAW"; + family = "CeBr3/RAW"; + + FillSpectra(family,name,RawData->Get_Time(i)); + } +} + + + +//////////////////////////////////////////////////////////////////////////////// +void TCeBr3Spectra::FillPreTreatedSpectra(TCeBr3Data* PreTreatedData) { + static string name; + static string family; + + // Energy + unsigned int sizeE = PreTreatedData->GetMultEnergy(); + for (unsigned int i = 0; i < sizeE; i++) { + name = "CeBr3"+NPL::itoa(PreTreatedData->GetE_DetectorNbr(i))+"_ENERGY_CAL"; + family = "CeBr3/CAL"; + + FillSpectra(family,name,PreTreatedData->Get_Energy(i)); + } + + // Time + unsigned int sizeT = PreTreatedData->GetMultTime(); + for (unsigned int i = 0; i < sizeT; i++) { + name = "CeBr3"+NPL::itoa(PreTreatedData->GetT_DetectorNbr(i))+"_TIME_CAL"; + family = "CeBr3/CAL"; + + FillSpectra(family,name,PreTreatedData->Get_Time(i)); + } +} + + + +//////////////////////////////////////////////////////////////////////////////// +void TCeBr3Spectra::FillPhysicsSpectra(TCeBr3Physics* Physics) { + static string name; + static string family; + family= "CeBr3/PHY"; + + // Energy vs time + unsigned int sizeE = Physics->Energy.size(); + for(unsigned int i = 0 ; i < sizeE ; i++){ + name = "CeBr3_ENERGY_TIME"; + FillSpectra(family,name,Physics->Energy[i],Physics->Time[i]); + } +} + diff --git a/NPLib/Detectors/CeBr3/TCeBr3Spectra.h b/NPLib/Detectors/CeBr3/TCeBr3Spectra.h new file mode 100644 index 000000000..371f0aaf5 --- /dev/null +++ b/NPLib/Detectors/CeBr3/TCeBr3Spectra.h @@ -0,0 +1,62 @@ +#ifndef TCeBr3SPECTRA_H +#define TCeBr3SPECTRA_H +/***************************************************************************** + * Copyright (C) 2009-2023 this file is part of the NPTool Project * + * * + * For the licensing terms see $NPTOOL/Licence/NPTool_Licence * + * For the list of contributors see $NPTOOL/Licence/Contributors * + *****************************************************************************/ + +/***************************************************************************** + * Original Author: Leo Plagnol contact address: plagnol@ijclab.in2p3.fr * + * * + * Creation Date : December 2023 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class hold CeBr3 Spectra * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + * * + *****************************************************************************/ + +// NPLib headers +#include "NPVSpectra.h" +#include "TCeBr3Data.h" +#include "TCeBr3Physics.h" + +// Forward Declaration +class TCeBr3Physics; + + +class TCeBr3Spectra : public VSpectra { + ////////////////////////////////////////////////////////////// + // constructor and destructor + public: + TCeBr3Spectra(); + TCeBr3Spectra(unsigned int NumberOfDetectors); + ~TCeBr3Spectra(); + + ////////////////////////////////////////////////////////////// + // Initialization methods + private: + void InitRawSpectra(); + void InitPreTreatedSpectra(); + void InitPhysicsSpectra(); + + ////////////////////////////////////////////////////////////// + // Filling methods + public: + void FillRawSpectra(TCeBr3Data*); + void FillPreTreatedSpectra(TCeBr3Data*); + void FillPhysicsSpectra(TCeBr3Physics*); + + ////////////////////////////////////////////////////////////// + // Detector parameters + private: + unsigned int fNumberOfDetectors; +}; + +#endif diff --git a/NPLib/Detectors/GeLi/CMakeLists.txt b/NPLib/Detectors/GeLi/CMakeLists.txt new file mode 100644 index 000000000..761e369fd --- /dev/null +++ b/NPLib/Detectors/GeLi/CMakeLists.txt @@ -0,0 +1,6 @@ +add_custom_command(OUTPUT TGeLiPhysicsDict.cxx COMMAND ../../scripts/build_dict.sh TGeLiPhysics.h TGeLiPhysicsDict.cxx TGeLiPhysics.rootmap libNPGeLi.dylib DEPENDS TGeLiPhysics.h) +add_custom_command(OUTPUT TGeLiDataDict.cxx COMMAND ../../scripts/build_dict.sh TGeLiData.h TGeLiDataDict.cxx TGeLiData.rootmap libNPGeLi.dylib DEPENDS TGeLiData.h) +add_library(NPGeLi SHARED TGeLiSpectra.cxx TGeLiData.cxx TGeLiPhysics.cxx TGeLiDataDict.cxx TGeLiPhysicsDict.cxx ) +target_link_libraries(NPGeLi ${ROOT_LIBRARIES} NPCore) +install(FILES TGeLiData.h TGeLiPhysics.h TGeLiSpectra.h DESTINATION ${CMAKE_INCLUDE_OUTPUT_DIRECTORY}) + diff --git a/NPLib/Detectors/GeLi/TGeLiData.cxx b/NPLib/Detectors/GeLi/TGeLiData.cxx new file mode 100644 index 000000000..96b87bb77 --- /dev/null +++ b/NPLib/Detectors/GeLi/TGeLiData.cxx @@ -0,0 +1,79 @@ +/***************************************************************************** + * Copyright (C) 2009-2023 this file is part of the NPTool Project * + * * + * For the licensing terms see $NPTOOL/Licence/NPTool_Licence * + * For the list of contributors see $NPTOOL/Licence/Contributors * + *****************************************************************************/ + +/***************************************************************************** + * Original Author: Leo Plagnol contact address: plagnol@ijclab.in2p3.fr * + * * + * Creation Date : December 2023 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class hold GeLi Raw data * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + * * + *****************************************************************************/ +#include "TGeLiData.h" + +#include <iostream> +#include <fstream> +#include <sstream> +#include <string> +using namespace std; + +ClassImp(TGeLiData) + + +////////////////////////////////////////////////////////////////////// +TGeLiData::TGeLiData() { +} + + + +////////////////////////////////////////////////////////////////////// +TGeLiData::~TGeLiData() { +} + + + +////////////////////////////////////////////////////////////////////// +void TGeLiData::Clear() { + // Energy + fGeLi_E_DetectorNbr.clear(); + fGeLi_Energy.clear(); + // Time + fGeLi_T_DetectorNbr.clear(); + fGeLi_Time.clear(); +} + + + +////////////////////////////////////////////////////////////////////// +void TGeLiData::Dump() const { + // This method is very useful for debuging and worth the dev. + cout << "XXXXXXXXXXXXXXXXXXXXXXXX New Event [TGeLiData::Dump()] XXXXXXXXXXXXXXXXX" << endl; + + // Energy + size_t mysize = fGeLi_E_DetectorNbr.size(); + cout << "GeLi_E_Mult: " << mysize << endl; + + for (size_t i = 0 ; i < mysize ; i++){ + cout << "DetNbr: " << fGeLi_E_DetectorNbr[i] + << " Energy: " << fGeLi_Energy[i]; + } + + // Time + mysize = fGeLi_T_DetectorNbr.size(); + cout << "GeLi_T_Mult: " << mysize << endl; + + for (size_t i = 0 ; i < mysize ; i++){ + cout << "DetNbr: " << fGeLi_T_DetectorNbr[i] + << " Time: " << fGeLi_Time[i]; + } +} diff --git a/NPLib/Detectors/GeLi/TGeLiData.h b/NPLib/Detectors/GeLi/TGeLiData.h new file mode 100644 index 000000000..062966933 --- /dev/null +++ b/NPLib/Detectors/GeLi/TGeLiData.h @@ -0,0 +1,104 @@ +#ifndef __GeLiDATA__ +#define __GeLiDATA__ +/***************************************************************************** + * Copyright (C) 2009-2023 this file is part of the NPTool Project * + * * + * For the licensing terms see $NPTOOL/Licence/NPTool_Licence * + * For the list of contributors see $NPTOOL/Licence/Contributors * + *****************************************************************************/ + +/***************************************************************************** + * Original Author: Leo Plagnol contact address: plagnol@ijclab.in2p3.fr * + * * + * Creation Date : December 2023 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class hold GeLi Raw data * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + * * + *****************************************************************************/ + +// STL +#include <vector> +using namespace std; + +// ROOT +#include "TObject.h" + +class TGeLiData : public TObject { + ////////////////////////////////////////////////////////////// + // data members are hold into vectors in order + // to allow multiplicity treatment + private: + // Energy + vector<UShort_t> fGeLi_E_DetectorNbr; + vector<Double_t> fGeLi_Energy; + + // Time + vector<UShort_t> fGeLi_T_DetectorNbr; + vector<Double_t> fGeLi_Time; + + + ////////////////////////////////////////////////////////////// + // Constructor and destructor + public: + TGeLiData(); + ~TGeLiData(); + + + ////////////////////////////////////////////////////////////// + // Inherited from TObject and overriden to avoid warnings + public: + void Clear(); + void Clear(const Option_t*) {}; + void Dump() const; + + + ////////////////////////////////////////////////////////////// + // Getters and Setters + // Prefer inline declaration to avoid unnecessary called of + // frequently used methods + // add //! to avoid ROOT creating dictionnary for the methods + public: + ////////////////////// SETTERS //////////////////////// + // Energy + inline void SetEnergy(const UShort_t& DetNbr,const Double_t& Energy){ + fGeLi_E_DetectorNbr.push_back(DetNbr); + fGeLi_Energy.push_back(Energy); + };//! + + // Time + inline void SetTime(const UShort_t& DetNbr,const Double_t& Time) { + fGeLi_T_DetectorNbr.push_back(DetNbr); + fGeLi_Time.push_back(Time); + };//! + + + ////////////////////// GETTERS //////////////////////// + // Energy + inline UShort_t GetMultEnergy() const + {return fGeLi_E_DetectorNbr.size();} + inline UShort_t GetE_DetectorNbr(const unsigned int &i) const + {return fGeLi_E_DetectorNbr[i];}//! + inline Double_t Get_Energy(const unsigned int &i) const + {return fGeLi_Energy[i];}//! + + // Time + inline UShort_t GetMultTime() const + {return fGeLi_T_DetectorNbr.size();} + inline UShort_t GetT_DetectorNbr(const unsigned int &i) const + {return fGeLi_T_DetectorNbr[i];}//! + inline Double_t Get_Time(const unsigned int &i) const + {return fGeLi_Time[i];}//! + + + ////////////////////////////////////////////////////////////// + // Required for ROOT dictionnary + ClassDef(TGeLiData,1) // GeLiData structure +}; + +#endif diff --git a/NPLib/Detectors/GeLi/TGeLiPhysics.cxx b/NPLib/Detectors/GeLi/TGeLiPhysics.cxx new file mode 100644 index 000000000..d6bc11f40 --- /dev/null +++ b/NPLib/Detectors/GeLi/TGeLiPhysics.cxx @@ -0,0 +1,344 @@ +/***************************************************************************** + * Copyright (C) 2009-2023 this file is part of the NPTool Project * + * * + * For the licensing terms see $NPTOOL/Licence/NPTool_Licence * + * For the list of contributors see $NPTOOL/Licence/Contributors * + *****************************************************************************/ + +/***************************************************************************** + * Original Author: Leo Plagnol contact address: plagnol@ijclab.in2p3.fr * + * * + * Creation Date : December 2023 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class hold GeLi Treated data * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + * * + *****************************************************************************/ + +#include "TGeLiPhysics.h" + +// STL +#include <sstream> +#include <iostream> +#include <cmath> +#include <stdlib.h> +#include <limits> +using namespace std; + +// NPL +#include "RootInput.h" +#include "RootOutput.h" +#include "NPDetectorFactory.h" +#include "NPOptionManager.h" + +// ROOT +#include "TChain.h" + +ClassImp(TGeLiPhysics) + + +/////////////////////////////////////////////////////////////////////////// +TGeLiPhysics::TGeLiPhysics() + : m_EventData(new TGeLiData), + m_PreTreatedData(new TGeLiData), + m_EventPhysics(this), + m_Spectra(0), + m_E_RAW_Threshold(0), // adc channels + m_E_Threshold(0), // MeV + m_NumberOfDetectors(0) { +} + +/////////////////////////////////////////////////////////////////////////// +/// A usefull method to bundle all operation to add a detector +void TGeLiPhysics::AddDetector(TVector3 , string ){ + // In That simple case nothing is done + // Typically for more complex detector one would calculate the relevant + // positions (stripped silicon) or angles (gamma array) + m_NumberOfDetectors++; +} + +/////////////////////////////////////////////////////////////////////////// +void TGeLiPhysics::AddDetector(double R, double Theta, double Phi, string shape){ + // Compute the TVector3 corresponding + TVector3 Pos(R*sin(Theta)*cos(Phi),R*sin(Theta)*sin(Phi),R*cos(Theta)); + // Call the cartesian method + AddDetector(Pos,shape); +} + +/////////////////////////////////////////////////////////////////////////// +void TGeLiPhysics::BuildSimplePhysicalEvent() { + BuildPhysicalEvent(); +} + + + +/////////////////////////////////////////////////////////////////////////// +void TGeLiPhysics::BuildPhysicalEvent() { + // apply thresholds and calibration + PreTreat(); + + // match energy and time together + unsigned int mysizeE = m_PreTreatedData->GetMultEnergy(); + unsigned int mysizeT = m_PreTreatedData->GetMultTime(); + for (UShort_t e = 0; e < mysizeE ; e++) { + for (UShort_t t = 0; t < mysizeT ; t++) { + if (m_PreTreatedData->GetE_DetectorNbr(e) == m_PreTreatedData->GetT_DetectorNbr(t)) { + DetectorNumber.push_back(m_PreTreatedData->GetE_DetectorNbr(e)); + Energy.push_back(m_PreTreatedData->Get_Energy(e)); + Time.push_back(m_PreTreatedData->Get_Time(t)); + } + } + } +} + +/////////////////////////////////////////////////////////////////////////// +void TGeLiPhysics::PreTreat() { + // This method typically applies thresholds and calibrations + // Might test for disabled channels for more complex detector + + // clear pre-treated object + ClearPreTreatedData(); + + // instantiate CalibrationManager + static CalibrationManager* Cal = CalibrationManager::getInstance(); + + // Energy + unsigned int mysize = m_EventData->GetMultEnergy(); + for (UShort_t i = 0; i < mysize ; ++i) { + if (m_EventData->Get_Energy(i) > m_E_RAW_Threshold) { + Double_t Energy = Cal->ApplyCalibration("GeLi/ENERGY"+NPL::itoa(m_EventData->GetE_DetectorNbr(i)),m_EventData->Get_Energy(i)); + if (Energy > m_E_Threshold) { + m_PreTreatedData->SetEnergy(m_EventData->GetE_DetectorNbr(i), Energy); + } + } + } + + // Time + mysize = m_EventData->GetMultTime(); + for (UShort_t i = 0; i < mysize; ++i) { + Double_t Time= Cal->ApplyCalibration("GeLi/TIME"+NPL::itoa(m_EventData->GetT_DetectorNbr(i)),m_EventData->Get_Time(i)); + m_PreTreatedData->SetTime(m_EventData->GetT_DetectorNbr(i), Time); + } +} + + + +/////////////////////////////////////////////////////////////////////////// +void TGeLiPhysics::ReadAnalysisConfig() { + bool ReadingStatus = false; + + // path to file + string FileName = "./configs/ConfigGeLi.dat"; + + // open analysis config file + ifstream AnalysisConfigFile; + AnalysisConfigFile.open(FileName.c_str()); + + if (!AnalysisConfigFile.is_open()) { + cout << " No ConfigGeLi.dat found: Default parameter loaded for Analayis " << FileName << endl; + return; + } + cout << " Loading user parameter for Analysis from ConfigGeLi.dat " << endl; + + // Save it in a TAsciiFile + TAsciiFile* asciiConfig = RootOutput::getInstance()->GetAsciiFileAnalysisConfig(); + asciiConfig->AppendLine("%%% ConfigGeLi.dat %%%"); + asciiConfig->Append(FileName.c_str()); + asciiConfig->AppendLine(""); + // read analysis config file + string LineBuffer,DataBuffer,whatToDo; + while (!AnalysisConfigFile.eof()) { + // Pick-up next line + getline(AnalysisConfigFile, LineBuffer); + + // search for "header" + string name = "ConfigGeLi"; + if (LineBuffer.compare(0, name.length(), name) == 0) + ReadingStatus = true; + + // loop on tokens and data + while (ReadingStatus ) { + whatToDo=""; + AnalysisConfigFile >> whatToDo; + + // Search for comment symbol (%) + if (whatToDo.compare(0, 1, "%") == 0) { + AnalysisConfigFile.ignore(numeric_limits<streamsize>::max(), '\n' ); + } + + else if (whatToDo=="E_RAW_THRESHOLD") { + AnalysisConfigFile >> DataBuffer; + m_E_RAW_Threshold = atof(DataBuffer.c_str()); + cout << whatToDo << " " << m_E_RAW_Threshold << endl; + } + + else if (whatToDo=="E_THRESHOLD") { + AnalysisConfigFile >> DataBuffer; + m_E_Threshold = atof(DataBuffer.c_str()); + cout << whatToDo << " " << m_E_Threshold << endl; + } + + else { + ReadingStatus = false; + } + } + } +} + + + +/////////////////////////////////////////////////////////////////////////// +void TGeLiPhysics::Clear() { + DetectorNumber.clear(); + Energy.clear(); + Time.clear(); +} + + + +/////////////////////////////////////////////////////////////////////////// +void TGeLiPhysics::ReadConfiguration(NPL::InputParser parser) { + vector<NPL::InputBlock*> blocks = parser.GetAllBlocksWithToken("GeLi"); + if(NPOptionManager::getInstance()->GetVerboseLevel()) + cout << "//// " << blocks.size() << " detectors found " << endl; + + vector<string> cart = {"POS","Shape"}; + vector<string> sphe = {"R","Theta","Phi","Shape"}; + + for(unsigned int i = 0 ; i < blocks.size() ; i++){ + if(blocks[i]->HasTokenList(cart)){ + if(NPOptionManager::getInstance()->GetVerboseLevel()) + cout << endl << "//// GeLi " << i+1 << endl; + + TVector3 Pos = blocks[i]->GetTVector3("POS","mm"); + string Shape = blocks[i]->GetString("Shape"); + AddDetector(Pos,Shape); + } + else if(blocks[i]->HasTokenList(sphe)){ + if(NPOptionManager::getInstance()->GetVerboseLevel()) + cout << endl << "//// GeLi " << i+1 << endl; + double R = blocks[i]->GetDouble("R","mm"); + double Theta = blocks[i]->GetDouble("Theta","deg"); + double Phi = blocks[i]->GetDouble("Phi","deg"); + string Shape = blocks[i]->GetString("Shape"); + AddDetector(R,Theta,Phi,Shape); + } + else{ + cout << "ERROR: check your input file formatting " << endl; + exit(1); + } + } +} + +/////////////////////////////////////////////////////////////////////////// +void TGeLiPhysics::InitSpectra() { + m_Spectra = new TGeLiSpectra(m_NumberOfDetectors); +} + + + +/////////////////////////////////////////////////////////////////////////// +void TGeLiPhysics::FillSpectra() { + m_Spectra -> FillRawSpectra(m_EventData); + m_Spectra -> FillPreTreatedSpectra(m_PreTreatedData); + m_Spectra -> FillPhysicsSpectra(m_EventPhysics); +} + + + +/////////////////////////////////////////////////////////////////////////// +void TGeLiPhysics::CheckSpectra() { + m_Spectra->CheckSpectra(); +} + + + +/////////////////////////////////////////////////////////////////////////// +void TGeLiPhysics::ClearSpectra() { + // To be done +} + + + +/////////////////////////////////////////////////////////////////////////// +map< string , TH1*> TGeLiPhysics::GetSpectra() { + if(m_Spectra) + return m_Spectra->GetMapHisto(); + else{ + map< string , TH1*> empty; + return empty; + } +} + +/////////////////////////////////////////////////////////////////////////// +void TGeLiPhysics::WriteSpectra() { + m_Spectra->WriteSpectra(); +} + + + +/////////////////////////////////////////////////////////////////////////// +void TGeLiPhysics::AddParameterToCalibrationManager() { + CalibrationManager* Cal = CalibrationManager::getInstance(); + for (int i = 0; i < m_NumberOfDetectors; ++i) { + Cal->AddParameter("GeLi", "D"+ NPL::itoa(i+1)+"_ENERGY","GeLi_D"+ NPL::itoa(i+1)+"_ENERGY"); + Cal->AddParameter("GeLi", "D"+ NPL::itoa(i+1)+"_TIME","GeLi_D"+ NPL::itoa(i+1)+"_TIME"); + } +} + + + +/////////////////////////////////////////////////////////////////////////// +void TGeLiPhysics::InitializeRootInputRaw() { + TChain* inputChain = RootInput::getInstance()->GetChain(); + inputChain->SetBranchStatus("GeLi", true ); + inputChain->SetBranchAddress("GeLi", &m_EventData ); +} + + + +/////////////////////////////////////////////////////////////////////////// +void TGeLiPhysics::InitializeRootInputPhysics() { + TChain* inputChain = RootInput::getInstance()->GetChain(); + inputChain->SetBranchAddress("GeLi", &m_EventPhysics); +} + + + +/////////////////////////////////////////////////////////////////////////// +void TGeLiPhysics::InitializeRootOutput() { + TTree* outputTree = RootOutput::getInstance()->GetTree(); + outputTree->Branch("GeLi", "TGeLiPhysics", &m_EventPhysics); +} + + + +//////////////////////////////////////////////////////////////////////////////// +// Construct Method to be pass to the DetectorFactory // +//////////////////////////////////////////////////////////////////////////////// +NPL::VDetector* TGeLiPhysics::Construct() { + return (NPL::VDetector*) new TGeLiPhysics(); +} + + + +//////////////////////////////////////////////////////////////////////////////// +// Registering the construct method to the factory // +//////////////////////////////////////////////////////////////////////////////// +extern "C"{ +class proxy_GeLi{ + public: + proxy_GeLi(){ + NPL::DetectorFactory::getInstance()->AddToken("GeLi","GeLi"); + NPL::DetectorFactory::getInstance()->AddDetector("GeLi",TGeLiPhysics::Construct); + } +}; + +proxy_GeLi p_GeLi; +} + diff --git a/NPLib/Detectors/GeLi/TGeLiPhysics.h b/NPLib/Detectors/GeLi/TGeLiPhysics.h new file mode 100644 index 000000000..c6bff08fc --- /dev/null +++ b/NPLib/Detectors/GeLi/TGeLiPhysics.h @@ -0,0 +1,180 @@ +#ifndef TGeLiPHYSICS_H +#define TGeLiPHYSICS_H +/***************************************************************************** + * Copyright (C) 2009-2023 this file is part of the NPTool Project * + * * + * For the licensing terms see $NPTOOL/Licence/NPTool_Licence * + * For the list of contributors see $NPTOOL/Licence/Contributors * + *****************************************************************************/ + +/***************************************************************************** + * Original Author: Leo Plagnol contact address: plagnol@ijclab.in2p3.fr * + * * + * Creation Date : December 2023 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class hold GeLi Treated data * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + * * + *****************************************************************************/ + +// C++ headers +#include <vector> +#include <map> +#include <string> +using namespace std; + +// ROOT headers +#include "TObject.h" +#include "TH1.h" +#include "TVector3.h" +// NPTool headers +#include "TGeLiData.h" +#include "TGeLiSpectra.h" +#include "NPCalibrationManager.h" +#include "NPVDetector.h" +#include "NPInputParser.h" +// forward declaration +class TGeLiSpectra; + + + +class TGeLiPhysics : public TObject, public NPL::VDetector { + ////////////////////////////////////////////////////////////// + // constructor and destructor + public: + TGeLiPhysics(); + ~TGeLiPhysics() {}; + + + ////////////////////////////////////////////////////////////// + // Inherited from TObject and overriden to avoid warnings + public: + void Clear(); + void Clear(const Option_t*) {}; + + + ////////////////////////////////////////////////////////////// + // data obtained after BuildPhysicalEvent() and stored in + // output ROOT file + public: + vector<int> DetectorNumber; + vector<double> Energy; + vector<double> Time; + + /// A usefull method to bundle all operation to add a detector + void AddDetector(TVector3 POS, string shape); + void AddDetector(double R, double Theta, double Phi, string shape); + + ////////////////////////////////////////////////////////////// + // methods inherited from the VDetector ABC class + public: + // read stream from ConfigFile to pick-up detector parameters + void ReadConfiguration(NPL::InputParser); + + // add parameters to the CalibrationManger + void AddParameterToCalibrationManager(); + + // method called event by event, aiming at extracting the + // physical information from detector + void BuildPhysicalEvent(); + + // same as BuildPhysicalEvent() method but with a simpler + // treatment + void BuildSimplePhysicalEvent(); + + // same as above but for online analysis + void BuildOnlinePhysicalEvent() {BuildPhysicalEvent();}; + + // activate raw data object and branches from input TChain + // in this method mother branches (Detector) AND daughter leaves + // (fDetector_parameter) have to be activated + void InitializeRootInputRaw(); + + // activate physics data object and branches from input TChain + // in this method mother branches (Detector) AND daughter leaves + // (fDetector_parameter) have to be activated + void InitializeRootInputPhysics(); + + // create branches of output ROOT file + void InitializeRootOutput(); + + // clear the raw and physical data objects event by event + void ClearEventPhysics() {Clear();} + void ClearEventData() {m_EventData->Clear();} + + // methods related to the TGeLiSpectra class + // instantiate the TGeLiSpectra class and + // declare list of histograms + void InitSpectra(); + + // fill the spectra + void FillSpectra(); + + // used for Online mainly, sanity check for histograms and + // change their color if issues are found, for example + void CheckSpectra(); + + // used for Online only, clear all the spectra + void ClearSpectra(); + + // write spectra to ROOT output file + void WriteSpectra(); + + + ////////////////////////////////////////////////////////////// + // specific methods to GeLi array + public: + // remove bad channels, calibrate the data and apply thresholds + void PreTreat(); + + // clear the pre-treated object + void ClearPreTreatedData() {m_PreTreatedData->Clear();} + + // read the user configuration file. If no file is found, load standard one + void ReadAnalysisConfig(); + + // give and external TGeLiData object to TGeLiPhysics. + // needed for online analysis for example + void SetRawDataPointer(TGeLiData* rawDataPointer) {m_EventData = rawDataPointer;} + + // objects are not written in the TTree + private: + TGeLiData* m_EventData; //! + TGeLiData* m_PreTreatedData; //! + TGeLiPhysics* m_EventPhysics; //! + + // getters for raw and pre-treated data object + public: + TGeLiData* GetRawData() const {return m_EventData;} + TGeLiData* GetPreTreatedData() const {return m_PreTreatedData;} + + // parameters used in the analysis + private: + // thresholds + double m_E_RAW_Threshold; //! + double m_E_Threshold; //! + + // number of detectors + private: + int m_NumberOfDetectors; //! + + // spectra class + private: + TGeLiSpectra* m_Spectra; // ! + + // spectra getter + public: + map<string, TH1*> GetSpectra(); + + // Static constructor to be passed to the Detector Factory + public: + static NPL::VDetector* Construct(); + + ClassDef(TGeLiPhysics,1) // GeLiPhysics structure +}; +#endif diff --git a/NPLib/Detectors/GeLi/TGeLiSpectra.cxx b/NPLib/Detectors/GeLi/TGeLiSpectra.cxx new file mode 100644 index 000000000..41a38f1ba --- /dev/null +++ b/NPLib/Detectors/GeLi/TGeLiSpectra.cxx @@ -0,0 +1,174 @@ +/***************************************************************************** + * Copyright (C) 2009-2023 this file is part of the NPTool Project * + * * + * For the licensing terms see $NPTOOL/Licence/NPTool_Licence * + * For the list of contributors see $NPTOOL/Licence/Contributors * + *****************************************************************************/ + +/***************************************************************************** + * Original Author: Leo Plagnol contact address: plagnol@ijclab.in2p3.fr * + * * + * Creation Date : December 2023 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class hold GeLi Spectra * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + * * + *****************************************************************************/ + +// class header +#include "TGeLiSpectra.h" + +// STL +#include <iostream> +#include <string> +using namespace std; + +// NPTool header +#include "NPOptionManager.h" + + + +//////////////////////////////////////////////////////////////////////////////// +TGeLiSpectra::TGeLiSpectra() + : fNumberOfDetectors(0) { + SetName("GeLi"); +} + + + +//////////////////////////////////////////////////////////////////////////////// +TGeLiSpectra::TGeLiSpectra(unsigned int NumberOfDetectors) { + if(NPOptionManager::getInstance()->GetVerboseLevel()>0) + cout << "************************************************" << endl + << "TGeLiSpectra : Initalizing control spectra for " + << NumberOfDetectors << " Detectors" << endl + << "************************************************" << endl ; + SetName("GeLi"); + fNumberOfDetectors = NumberOfDetectors; + + InitRawSpectra(); + InitPreTreatedSpectra(); + InitPhysicsSpectra(); +} + + + +//////////////////////////////////////////////////////////////////////////////// +TGeLiSpectra::~TGeLiSpectra() { +} + + + +//////////////////////////////////////////////////////////////////////////////// +void TGeLiSpectra::InitRawSpectra() { + static string name; + for (unsigned int i = 0; i < fNumberOfDetectors; i++) { // loop on number of detectors + // Energy + name = "GeLi"+NPL::itoa(i+1)+"_ENERGY_RAW"; + AddHisto1D(name, name, 4096, 0, 16384, "GeLi/RAW"); + // Time + name = "GeLi"+NPL::itoa(i+1)+"_TIME_RAW"; + AddHisto1D(name, name, 4096, 0, 16384, "GeLi/RAW"); + } // end loop on number of detectors +} + + + +//////////////////////////////////////////////////////////////////////////////// +void TGeLiSpectra::InitPreTreatedSpectra() { + static string name; + for (unsigned int i = 0; i < fNumberOfDetectors; i++) { // loop on number of detectors + // Energy + name = "GeLi"+NPL::itoa(i+1)+"_ENERGY_CAL"; + AddHisto1D(name, name, 500, 0, 25, "GeLi/CAL"); + // Time + name = "GeLi"+NPL::itoa(i+1)+"_TIME_CAL"; + AddHisto1D(name, name, 500, 0, 25, "GeLi/CAL"); + + + } // end loop on number of detectors +} + + + +//////////////////////////////////////////////////////////////////////////////// +void TGeLiSpectra::InitPhysicsSpectra() { + static string name; + // Kinematic Plot + name = "GeLi_ENERGY_TIME"; + AddHisto2D(name, name, 500, 0, 500, 500, 0, 50, "GeLi/PHY"); +} + + + +//////////////////////////////////////////////////////////////////////////////// +void TGeLiSpectra::FillRawSpectra(TGeLiData* RawData) { + static string name; + static string family; + + // Energy + unsigned int sizeE = RawData->GetMultEnergy(); + for (unsigned int i = 0; i < sizeE; i++) { + name = "GeLi"+NPL::itoa(RawData->GetE_DetectorNbr(i))+"_ENERGY_RAW"; + family = "GeLi/RAW"; + + FillSpectra(family,name,RawData->Get_Energy(i)); + } + + // Time + unsigned int sizeT = RawData->GetMultTime(); + for (unsigned int i = 0; i < sizeT; i++) { + name = "GeLi"+NPL::itoa(RawData->GetT_DetectorNbr(i))+"_TIME_RAW"; + family = "GeLi/RAW"; + + FillSpectra(family,name,RawData->Get_Time(i)); + } +} + + + +//////////////////////////////////////////////////////////////////////////////// +void TGeLiSpectra::FillPreTreatedSpectra(TGeLiData* PreTreatedData) { + static string name; + static string family; + + // Energy + unsigned int sizeE = PreTreatedData->GetMultEnergy(); + for (unsigned int i = 0; i < sizeE; i++) { + name = "GeLi"+NPL::itoa(PreTreatedData->GetE_DetectorNbr(i))+"_ENERGY_CAL"; + family = "GeLi/CAL"; + + FillSpectra(family,name,PreTreatedData->Get_Energy(i)); + } + + // Time + unsigned int sizeT = PreTreatedData->GetMultTime(); + for (unsigned int i = 0; i < sizeT; i++) { + name = "GeLi"+NPL::itoa(PreTreatedData->GetT_DetectorNbr(i))+"_TIME_CAL"; + family = "GeLi/CAL"; + + FillSpectra(family,name,PreTreatedData->Get_Time(i)); + } +} + + + +//////////////////////////////////////////////////////////////////////////////// +void TGeLiSpectra::FillPhysicsSpectra(TGeLiPhysics* Physics) { + static string name; + static string family; + family= "GeLi/PHY"; + + // Energy vs time + unsigned int sizeE = Physics->Energy.size(); + for(unsigned int i = 0 ; i < sizeE ; i++){ + name = "GeLi_ENERGY_TIME"; + FillSpectra(family,name,Physics->Energy[i],Physics->Time[i]); + } +} + diff --git a/NPLib/Detectors/GeLi/TGeLiSpectra.h b/NPLib/Detectors/GeLi/TGeLiSpectra.h new file mode 100644 index 000000000..779ad27ba --- /dev/null +++ b/NPLib/Detectors/GeLi/TGeLiSpectra.h @@ -0,0 +1,62 @@ +#ifndef TGeLiSPECTRA_H +#define TGeLiSPECTRA_H +/***************************************************************************** + * Copyright (C) 2009-2023 this file is part of the NPTool Project * + * * + * For the licensing terms see $NPTOOL/Licence/NPTool_Licence * + * For the list of contributors see $NPTOOL/Licence/Contributors * + *****************************************************************************/ + +/***************************************************************************** + * Original Author: Leo Plagnol contact address: plagnol@ijclab.in2p3.fr * + * * + * Creation Date : December 2023 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class hold GeLi Spectra * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + * * + *****************************************************************************/ + +// NPLib headers +#include "NPVSpectra.h" +#include "TGeLiData.h" +#include "TGeLiPhysics.h" + +// Forward Declaration +class TGeLiPhysics; + + +class TGeLiSpectra : public VSpectra { + ////////////////////////////////////////////////////////////// + // constructor and destructor + public: + TGeLiSpectra(); + TGeLiSpectra(unsigned int NumberOfDetectors); + ~TGeLiSpectra(); + + ////////////////////////////////////////////////////////////// + // Initialization methods + private: + void InitRawSpectra(); + void InitPreTreatedSpectra(); + void InitPhysicsSpectra(); + + ////////////////////////////////////////////////////////////// + // Filling methods + public: + void FillRawSpectra(TGeLiData*); + void FillPreTreatedSpectra(TGeLiData*); + void FillPhysicsSpectra(TGeLiPhysics*); + + ////////////////////////////////////////////////////////////// + // Detector parameters + private: + unsigned int fNumberOfDetectors; +}; + +#endif diff --git a/NPLib/Detectors/quadranMSQ25/CMakeLists.txt b/NPLib/Detectors/quadranMSQ25/CMakeLists.txt new file mode 100644 index 000000000..d0cb6695c --- /dev/null +++ b/NPLib/Detectors/quadranMSQ25/CMakeLists.txt @@ -0,0 +1,6 @@ +add_custom_command(OUTPUT TquadranMSQ25PhysicsDict.cxx COMMAND ../../scripts/build_dict.sh TquadranMSQ25Physics.h TquadranMSQ25PhysicsDict.cxx TquadranMSQ25Physics.rootmap libNPquadranMSQ25.dylib DEPENDS TquadranMSQ25Physics.h) +add_custom_command(OUTPUT TquadranMSQ25DataDict.cxx COMMAND ../../scripts/build_dict.sh TquadranMSQ25Data.h TquadranMSQ25DataDict.cxx TquadranMSQ25Data.rootmap libNPquadranMSQ25.dylib DEPENDS TquadranMSQ25Data.h) +add_library(NPquadranMSQ25 SHARED TquadranMSQ25Data.cxx TquadranMSQ25Physics.cxx TquadranMSQ25DataDict.cxx TquadranMSQ25PhysicsDict.cxx ) +target_link_libraries(NPquadranMSQ25 ${ROOT_LIBRARIES} NPCore) +install(FILES TquadranMSQ25Data.h TquadranMSQ25Physics.h DESTINATION ${CMAKE_INCLUDE_OUTPUT_DIRECTORY}) + diff --git a/NPLib/Detectors/quadranMSQ25/TquadranMSQ25Data.cxx b/NPLib/Detectors/quadranMSQ25/TquadranMSQ25Data.cxx new file mode 100644 index 000000000..8b04886da --- /dev/null +++ b/NPLib/Detectors/quadranMSQ25/TquadranMSQ25Data.cxx @@ -0,0 +1,82 @@ +/***************************************************************************** + * Copyright (C) 2009-2016 this file is part of the NPTool Project * + * * + * For the licensing terms see $NPTOOL/Licence/NPTool_Licence * + * For the list of contributors see $NPTOOL/Licence/Contributors * + *****************************************************************************/ + +/***************************************************************************** + * Original Author: Adrien MATTA contact address: matta@lpccaen.in2p3.fr * + * * + * Creation Date : febuary 2009 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class hold quadranMSQ25 Raw data * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + * * + *****************************************************************************/ +#include <iostream> +using namespace std; + +#include "TquadranMSQ25Data.h" + +ClassImp(TquadranMSQ25Data) + +//////////////////////////////////////////////////////////////////////////////// +TquadranMSQ25Data::TquadranMSQ25Data(){ + // Default constructor + + // quadranMSQ25 + // Energy + fquadranMSQ25_StripE_DetectorNbr.clear(); + fquadranMSQ25_StripE_StripNbr.clear(); + fquadranMSQ25_StripE_Energy.clear(); + // Time + fquadranMSQ25_StripT_DetectorNbr.clear(); + fquadranMSQ25_StripT_StripNbr.clear(); + fquadranMSQ25_StripT_Time.clear(); + +} + +//////////////////////////////////////////////////////////////////////////////// +TquadranMSQ25Data::~TquadranMSQ25Data(){ +} + +//////////////////////////////////////////////////////////////////////////////// +void TquadranMSQ25Data::Clear(){ + // DSSD + // Energy + fquadranMSQ25_StripE_DetectorNbr.clear(); + fquadranMSQ25_StripE_StripNbr.clear(); + fquadranMSQ25_StripE_Energy.clear(); + // Time + fquadranMSQ25_StripT_DetectorNbr.clear(); + fquadranMSQ25_StripT_StripNbr.clear(); + fquadranMSQ25_StripT_Time.clear(); +} + + +//////////////////////////////////////////////////////////////////////////////// +void TquadranMSQ25Data::Dump() const{ + cout << "XXXXXXXXXXXXXXXXX New Event XXXXXXXXXXXXXXXXX" << endl; + + // quadranMSQ25 + // Energy + cout << "quadranMSQ25_StripE_Mult = " << fquadranMSQ25_StripE_DetectorNbr.size() << endl; + for (UShort_t i = 0; i < fquadranMSQ25_StripE_DetectorNbr.size(); i++) + cout << "DetNbr: " << fquadranMSQ25_StripE_DetectorNbr[i] + << " Strip: " << fquadranMSQ25_StripE_StripNbr[i] + << " Energy: " << fquadranMSQ25_StripE_Energy[i] << endl; + + // Time + cout << "quadranMSQ25_StripXT_Mult = " << fquadranMSQ25_StripT_DetectorNbr.size() << endl; + for (UShort_t i = 0; i < fquadranMSQ25_StripT_DetectorNbr.size(); i++) + cout << "DetNbr: " << fquadranMSQ25_StripT_DetectorNbr[i] + << " Strip: " << fquadranMSQ25_StripT_StripNbr[i] + << " Time: " << fquadranMSQ25_StripT_Time[i] << endl; + +} diff --git a/NPLib/Detectors/quadranMSQ25/TquadranMSQ25Data.h b/NPLib/Detectors/quadranMSQ25/TquadranMSQ25Data.h new file mode 100644 index 000000000..e7b8edb92 --- /dev/null +++ b/NPLib/Detectors/quadranMSQ25/TquadranMSQ25Data.h @@ -0,0 +1,75 @@ +#ifndef __quadranMSQ25DATA__ +#define __quadranMSQ25DATA__ +/***************************************************************************** + * Copyright (C) 2009-2016 this file is part of the NPTool Project * + * * + * For the licensing terms see $NPTOOL/Licence/NPTool_Licence * + * For the list of contributors see $NPTOOL/Licence/Contributors * + *****************************************************************************/ + +/***************************************************************************** + * Original Author: Adrien MATTA contact address: a.matta@surrey.ac.uk * + * * + * Creation Date : febuary 2009 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class hold the Single Side Striped Detector raw data * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + * * + *****************************************************************************/ +#include <vector> +#include "TObject.h" + +class TquadranMSQ25Data : public TObject { + private: + // quadranMSQ25 + // Energy + std::vector<UShort_t> fquadranMSQ25_StripE_DetectorNbr; + std::vector<UShort_t> fquadranMSQ25_StripE_StripNbr; + std::vector<Double_t> fquadranMSQ25_StripE_Energy; + // Time + std::vector<UShort_t> fquadranMSQ25_StripT_DetectorNbr; + std::vector<UShort_t> fquadranMSQ25_StripT_StripNbr; + std::vector<Double_t> fquadranMSQ25_StripT_Time; + + + public: + TquadranMSQ25Data(); + ~TquadranMSQ25Data(); + + void Clear(); + void Clear(const Option_t*) {}; + void Dump() const; + + ///////////////////// SETTERS //////////////////////// + // DSSD + // (X,E) + inline void SetEnergyDetectorNbr (const UShort_t& DetNbr) {fquadranMSQ25_StripE_DetectorNbr.push_back(DetNbr) ;} + inline void SetEnergyStripNbr (const UShort_t& StripNbr) {fquadranMSQ25_StripE_StripNbr.push_back(StripNbr) ;} + inline void SetEnergy (const Double_t& Energy) {fquadranMSQ25_StripE_Energy.push_back(Energy) ;} + // (X,T) + inline void SetTimeDetectorNbr (const UShort_t& DetNbr) {fquadranMSQ25_StripT_DetectorNbr.push_back(DetNbr) ;} + inline void SetTimeStripNbr (const UShort_t& StripNbr) {fquadranMSQ25_StripT_StripNbr.push_back(StripNbr) ;} + inline void SetTime (const Double_t& Time) {fquadranMSQ25_StripT_Time.push_back(Time) ;} + + ///////////////////// GETTERS //////////////////////// + // DSSD + // (X,E) + inline UShort_t GetEnergyMult () const {return fquadranMSQ25_StripE_DetectorNbr.size() ;} + inline UShort_t GetEnergyDetectorNbr (const Int_t& i) const {return fquadranMSQ25_StripE_DetectorNbr[i] ;} + inline UShort_t GetEnergyStripNbr (const Int_t& i) const {return fquadranMSQ25_StripE_StripNbr[i] ;} + inline Double_t GetEnergy (const Int_t& i) const {return fquadranMSQ25_StripE_Energy[i] ;} + // (X,T) + inline UShort_t GetTimeMult () const {return fquadranMSQ25_StripT_DetectorNbr.size() ;} + inline UShort_t GetTimeDetectorNbr (const Int_t& i) const {return fquadranMSQ25_StripT_DetectorNbr[i] ;} + inline UShort_t GetTimeStripNbr (const Int_t& i) const {return fquadranMSQ25_StripT_StripNbr[i] ;} + inline Double_t GetTime (const Int_t& i) const {return fquadranMSQ25_StripT_Time[i] ;} + + ClassDef(TquadranMSQ25Data,1) // quadranMSQ25Data structure +}; + +#endif diff --git a/NPLib/Detectors/quadranMSQ25/TquadranMSQ25Physics.cxx b/NPLib/Detectors/quadranMSQ25/TquadranMSQ25Physics.cxx new file mode 100644 index 000000000..c0a42d818 --- /dev/null +++ b/NPLib/Detectors/quadranMSQ25/TquadranMSQ25Physics.cxx @@ -0,0 +1,310 @@ +/***************************************************************************** + * Copyright (C) 2009-2016 this file is part of the NPTool Project * + * * + * For the licensing terms see $NPTOOL/Licence/NPTool_Licence * + * For the list of contributors see $NPTOOL/Licence/Contributors * + *****************************************************************************/ + +/***************************************************************************** + * Original Author: Adrien MATTA contact address: matta@lpccaen.in2p3.fr * + * * + * Creation Date : november 2009 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class hold quadranMSQ25 Physics * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + * * + *****************************************************************************/ +// NPL +#include "TquadranMSQ25Physics.h" +#include "RootOutput.h" +#include "RootInput.h" +#include "NPDetectorFactory.h" +#include "NPOptionManager.h" +// STL +#include <iostream> +#include <sstream> +#include <fstream> +#include <limits> +#include <stdlib.h> +using namespace std; +using namespace quadranMSQ25_LOCAL; +// ROOT +#include "TChain.h" + +ClassImp(TquadranMSQ25Physics) + /////////////////////////////////////////////////////////////////////////// + TquadranMSQ25Physics::TquadranMSQ25Physics(){ + NumberOfDetector = 0; + EventData = new TquadranMSQ25Data; + PreTreatedData = new TquadranMSQ25Data; + EventPhysics = this; + m_E_Threshold = 0; + m_Pedestal_Threshold = 0; + } +/////////////////////////////////////////////////////////////////////////// +TquadranMSQ25Physics::~TquadranMSQ25Physics() +{} +/////////////////////////////////////////////////////////////////////////// +void TquadranMSQ25Physics::Clear(){ + DetectorNumber .clear() ; + StripNumber .clear() ; + Energy .clear() ; + Time .clear() ; +} +/////////////////////////////////////////////////////////////////////////// +void TquadranMSQ25Physics::ReadConfiguration(NPL::InputParser parser) { + vector<NPL::InputBlock*> blocks = parser.GetAllBlocksWithToken("quadranMSQ25"); + if(NPOptionManager::getInstance()->GetVerboseLevel()) + cout << "//// " << blocks.size() << " detectors found " << endl; + + vector<string> cart = {"A","B","C","D"}; + vector<string> sphe = {"R","THETA","PHI","BETA"}; + + for(unsigned int i = 0 ; i < blocks.size() ; i++){ + if(blocks[i]->HasTokenList(cart)){ + if(NPOptionManager::getInstance()->GetVerboseLevel()) + cout << endl << "//// quadranMSQ25 " << i+1 << endl; + TVector3 A = blocks[i]->GetTVector3("A","mm"); + TVector3 B = blocks[i]->GetTVector3("B","mm"); + TVector3 C = blocks[i]->GetTVector3("C","mm"); + TVector3 D = blocks[i]->GetTVector3("D","mm"); + NumberOfDetector++; + } + else if(blocks[i]->HasTokenList(sphe)){ + if(NPOptionManager::getInstance()->GetVerboseLevel()) + cout << endl << "//// quadranMSQ25 " << i+1 << endl; + double R = blocks[i]->GetDouble("R","mm"); + double Theta = blocks[i]->GetDouble("THETA","deg"); + double Phi = blocks[i]->GetDouble("PHI","deg"); + vector<double> Beta = blocks[i]->GetVectorDouble("BETA","deg"); + NumberOfDetector++; + } + else{ + cout << "ERROR: check your input file formatting " << endl; + exit(1); + } + } + + InitializeStandardParameter() ; + ReadAnalysisConfig() ; +} + + +/////////////////////////////////////////////////////////////////////////// +void TquadranMSQ25Physics::AddParameterToCalibrationManager(){ + CalibrationManager* Cal = CalibrationManager::getInstance(); + + for(int i = 0 ; i < NumberOfDetector ; ++i){ + + for( int j = 0 ; j < 16 ; ++j){ + Cal->AddParameter("quadranMSQ25", "Detector"+ NPL::itoa(i+1)+"_Strip"+ NPL::itoa(j+1)+"_E","quadranMSQ25_DETECTOR_"+ NPL::itoa(i+1)+"_STRIP_"+ NPL::itoa(j+1)+"_E") ; + Cal->AddParameter("quadranMSQ25", "Detector"+ NPL::itoa(i+1)+"_Strip"+ NPL::itoa(j+1)+"_T","quadranMSQ25_DETECTOR_"+ NPL::itoa(i+1)+"_STRIP_"+ NPL::itoa(j+1)+"_T") ; + } + } +} + +/////////////////////////////////////////////////////////////////////////// +void TquadranMSQ25Physics::InitializeRootInputRaw(){ + TChain* inputChain = RootInput::getInstance()->GetChain(); + inputChain->SetBranchStatus ( "quadranMSQ25" , true ); + inputChain->SetBranchStatus ( "fquadranMSQ25_*" , true ); + inputChain->SetBranchAddress( "quadranMSQ25" , &EventData ); +} +/////////////////////////////////////////////////////////////////////////// +void TquadranMSQ25Physics::InitializeRootInputPhysics(){ + TChain* inputChain = RootInput::getInstance()->GetChain(); + inputChain->SetBranchStatus ( "quadranMSQ25" , true ); + inputChain->SetBranchStatus ( "DetectorNumber", true ); + inputChain->SetBranchStatus ( "StripNumber" , true ); + inputChain->SetBranchStatus ( "Energy" , true ); + inputChain->SetBranchStatus ( "Time" , true ); + inputChain->SetBranchAddress( "quadranMSQ25" , &EventPhysics ); + +} +/////////////////////////////////////////////////////////////////////////// +void TquadranMSQ25Physics::InitializeRootOutput(){ + TTree* outputTree = RootOutput::getInstance()->GetTree() ; + outputTree->Branch( "quadranMSQ25" , "TquadranMSQ25Physics" , &EventPhysics ) ; +} + +/////////////////////////////////////////////////////////////////////////// +void TquadranMSQ25Physics::BuildPhysicalEvent(){ + BuildSimplePhysicalEvent() ; +} + +/////////////////////////////////////////////////////////////////////////// +void TquadranMSQ25Physics::BuildSimplePhysicalEvent(){ + PreTreat(); + for(unsigned int i = 0 ; i < PreTreatedData->GetEnergyMult() ; ++i){ + DetectorNumber .push_back( PreTreatedData->GetEnergyDetectorNbr(i) ) ; + StripNumber .push_back( PreTreatedData->GetEnergyStripNbr(i) ) ; + Energy .push_back( PreTreatedData->GetEnergy(i) ) ; + // Look For associate Time + for(unsigned int j = 0 ; j < PreTreatedData->GetTimeMult() ; ++j ){ + if(PreTreatedData->GetEnergyDetectorNbr(i) == PreTreatedData->GetTimeDetectorNbr(j) && PreTreatedData->GetEnergyStripNbr(i)==PreTreatedData->GetTimeStripNbr(j)) + Time.push_back(PreTreatedData->GetTime(j)); + } + } + return; +} + +/////////////////////////////////////////////////////////////////////////// +void TquadranMSQ25Physics::PreTreat(){ + ClearPreTreatedData(); + + // E + for(int i = 0 ; i < EventData->GetEnergyMult() ; ++i){ + if(EventData->GetEnergy(i) > m_Pedestal_Threshold && ChannelStatus[EventData->GetEnergyDetectorNbr(i)-1][EventData->GetEnergyStripNbr(i)-1]){ + double E = fSi_E(EventData , i); + if( E > m_E_Threshold ){ + PreTreatedData->SetEnergyDetectorNbr( EventData->GetEnergyDetectorNbr(i) ) ; + PreTreatedData->SetEnergyStripNbr( EventData->GetEnergyStripNbr(i) ) ; + PreTreatedData->SetEnergy( E ) ; + } + } + } + // T + for(int i = 0 ; i < EventData->GetTimeMult() ; ++i){ + if(ChannelStatus[EventData->GetTimeDetectorNbr(i)-1][EventData->GetTimeStripNbr(i)-1]){ + PreTreatedData->SetTimeDetectorNbr( EventData->GetTimeDetectorNbr(i) ) ; + PreTreatedData->SetTimeStripNbr( EventData->GetTimeStripNbr(i) ) ; + PreTreatedData->SetTime( fSi_T(EventData , i) ) ; + } + } +} + +/////////////////////////////////////////////////////////////////////////// +void TquadranMSQ25Physics::InitializeStandardParameter(){ + // Enable all channel + vector<bool> TempChannelStatus; + ChannelStatus.clear(); + TempChannelStatus.resize(16,true); + for(int i = 0 ; i < NumberOfDetector ; ++i) + ChannelStatus[i] = TempChannelStatus; +} +/////////////////////////////////////////////////////////////////////////// +void TquadranMSQ25Physics::ReadAnalysisConfig(){ + bool ReadingStatus = false; + + // path to file + string FileName = "./configs/ConfigquadranMSQ25.dat"; + + // open analysis config file + ifstream AnalysisConfigFile; + AnalysisConfigFile.open(FileName.c_str()); + + if (!AnalysisConfigFile.is_open()) { + cout << " No ConfigMust2.dat found: Default parameter loaded for Analayis " << FileName << endl; + return; + } + cout << " Loading user parameter for Analysis from ConfigquadranMSQ25.dat " << endl; + + // Save it in a TAsciiFile + TAsciiFile* asciiConfig = RootOutput::getInstance()->GetAsciiFileAnalysisConfig(); + asciiConfig->AppendLine("%%% ConfigquadranMSQ25.dat %%%"); + asciiConfig->Append(FileName.c_str()); + asciiConfig->AppendLine(""); + + // read analysis config file + string LineBuffer,DataBuffer,whatToDo; + while (!AnalysisConfigFile.eof()) { + // Pick-up next line + getline(AnalysisConfigFile, LineBuffer); + + // search for "header" + if (LineBuffer.compare(0, 11, "ConfigquadranMSQ25") == 0) ReadingStatus = true; + + // loop on tokens and data + while (ReadingStatus) { + + whatToDo= "" ; + AnalysisConfigFile >> whatToDo; + + // Search for comment symbol (%) + if (whatToDo.compare(0, 1, "%") == 0) { + AnalysisConfigFile.ignore(numeric_limits<streamsize>::max(), '\n' ); + } + + else if (whatToDo=="PEDESTAL_THRESHOLD") { + AnalysisConfigFile >> DataBuffer; + m_Pedestal_Threshold = atof(DataBuffer.c_str() ); + cout << "PEDESTAL THRESHOLD " << m_Pedestal_Threshold << endl; + } + + + else if (whatToDo=="DISABLE_ALL") { + AnalysisConfigFile >> DataBuffer; + cout << whatToDo << " " << DataBuffer << endl; + int Detector = atoi(DataBuffer.substr(2,1).c_str()); + vector< bool > ChannelStatusBuffer; + ChannelStatusBuffer.resize(16,false); + ChannelStatus[Detector-1] = ChannelStatusBuffer; + } + + else if (whatToDo=="DISABLE_CHANNEL") { + AnalysisConfigFile >> DataBuffer; + cout << whatToDo << " " << DataBuffer << endl; + int telescope = atoi(DataBuffer.substr(2,1).c_str()); + int channel = -1; + if (DataBuffer.compare(3,3,"STR") == 0) { + channel = atoi(DataBuffer.substr(6).c_str()); + *(ChannelStatus[telescope-1].begin()+channel-1) = false; + } + + else { + cout << "Warning: detector type for quadranMSQ25 unknown!" << endl; + } + } + + else { + ReadingStatus = false; + } + } + } +} + + +/////////////////////////////////////////////////////////////////////////// +double quadranMSQ25_LOCAL::fSi_E( const TquadranMSQ25Data* EventData , const int i ){ + + static string str; + str = "quadranMSQ25/Detector" + NPL::itoa( EventData->GetEnergyDetectorNbr(i) ) + "_Strip" + NPL::itoa( EventData->GetEnergyStripNbr(i) ) +"_E"; + return CalibrationManager::getInstance()->ApplyCalibration( str, EventData->GetEnergy(i) ); +} + + +double quadranMSQ25_LOCAL::fSi_T( const TquadranMSQ25Data* EventData , const int i ){ + static string str; + str = "quadranMSQ25/Detector" + NPL::itoa( EventData->GetEnergyDetectorNbr(i) ) + "_Strip" + NPL::itoa( EventData->GetEnergyStripNbr(i) ) +"_T"; + return CalibrationManager::getInstance()->ApplyCalibration( str, EventData->GetTime(i) ); +} + + + +//////////////////////////////////////////////////////////////////////////////// +// Construct Method to be pass to the DetectorFactory // +//////////////////////////////////////////////////////////////////////////////// +NPL::VDetector* TquadranMSQ25Physics::Construct(){ + return (NPL::VDetector*) new TquadranMSQ25Physics(); +} + +//////////////////////////////////////////////////////////////////////////////// +// Registering the construct method to the factory // +//////////////////////////////////////////////////////////////////////////////// +extern "C"{ +class proxy_quadranmsq25{ + public: + proxy_quadranmsq25(){ + NPL::DetectorFactory::getInstance()->AddToken("quadranMSQ25","quadranMSQ25"); + NPL::DetectorFactory::getInstance()->AddDetector("quadranMSQ25",TquadranMSQ25Physics::Construct); + } +}; + +proxy_quadranmsq25 p; +} + diff --git a/NPLib/Detectors/quadranMSQ25/TquadranMSQ25Physics.h b/NPLib/Detectors/quadranMSQ25/TquadranMSQ25Physics.h new file mode 100644 index 000000000..d27b97251 --- /dev/null +++ b/NPLib/Detectors/quadranMSQ25/TquadranMSQ25Physics.h @@ -0,0 +1,132 @@ +#ifndef __quadranMSQ25Physics__ +#define __quadranMSQ25Physics__ +/***************************************************************************** + * Copyright (C) 2009-2016 this file is part of the NPTool Project * + * * + * For the licensing terms see $NPTOOL/Licence/NPTool_Licence * + * For the list of contributors see $NPTOOL/Licence/Contributors * + *****************************************************************************/ + +/***************************************************************************** + * Original Author: Adrien MATTA contact address: a.matta@surrey.ac.uk * + * * + * Creation Date : November 2009 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class hold the Single Side Striped Detector Physics * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + * * + *****************************************************************************/ +// STL +#include <vector> +using namespace std ; + +// ROOT +#include "TObject.h" + +// NPL +#include "TquadranMSQ25Data.h" +#include "NPVDetector.h" +#include "NPCalibrationManager.h" +#include "NPInputParser.h" + +class TquadranMSQ25Physics : public TObject, public NPL::VDetector{ + public: // Constructor and Destructor + TquadranMSQ25Physics(); + ~TquadranMSQ25Physics(); + + public: // Calibrated Data + vector<UShort_t> DetectorNumber; + vector<UShort_t> StripNumber; + vector<Double_t> Energy; + vector<Double_t> Time; + + public: // inherrited from VDetector + // Read stream at ConfigFile to pick-up parameters of detector (Position,...) using Token + void ReadConfiguration(NPL::InputParser); + + // Add Parameter to the CalibrationManger + void AddParameterToCalibrationManager(); + + // Activated associated Branches and link it to the private member DetectorData address + // In this method mother Branches (Detector) AND daughter leaf (fDetector_parameter) have to be activated + void InitializeRootInputRaw() ; + + // Activated associated Branches and link it to the private member DetectorPhysics address + // In this method mother Branches (Detector) AND daughter leaf (parameter) have to be activated + void InitializeRootInputPhysics() ; + + // Create associated branches and associated private member DetectorPhysics address + void InitializeRootOutput(); + + // This method is called at each event read from the Input Tree. Aime is to build treat Raw dat in order to extract physical parameter. + void BuildPhysicalEvent(); + + // Same as above, but only the simplest event and/or simple method are used (low multiplicity, faster algorythm but less efficient ...). + // This method aimed to be used for analysis performed during experiment, when speed is requiered. + // NB: This method can eventually be the same as BuildPhysicalEvent. + void BuildSimplePhysicalEvent(); + + // Same as above but for online analysis + void BuildOnlinePhysicalEvent() {BuildSimplePhysicalEvent();}; + + // Those two method all to clear the Event Physics or Data + void ClearEventPhysics() {Clear();} + void ClearEventData() {EventData->Clear();} + + + public: // Specific to quadranMSQ25 + // Clear The PreTeated object + void ClearPreTreatedData() {PreTreatedData->Clear();} + + // Remove bad channel, calibrate the data and apply threshold + void PreTreat(); + + // Initialize the standard parameter for analysis + // ie: all channel enable, maximum multiplicity for strip = number of telescope + void InitializeStandardParameter(); + + // Read the user configuration file; if no file found, load standard one + void ReadAnalysisConfig(); + + // Give and external TMustData object to TMust2Physics. Needed for online analysis for example. + void SetRawDataPointer(TquadranMSQ25Data* rawDataPointer) {EventData = rawDataPointer;} + // Retrieve raw and pre-treated data + TquadranMSQ25Data* GetRawData() const {return EventData;} + TquadranMSQ25Data* GetPreTreatedData() const {return PreTreatedData;} + + + private: // Data not written in the tree + int NumberOfDetector;//! + TquadranMSQ25Data* EventData;//! + TquadranMSQ25Data* PreTreatedData;//! + TquadranMSQ25Physics* EventPhysics;//! + + double m_E_Threshold;//! + double m_Pedestal_Threshold;//! + + + private: // Map of activated Channel + map< int, vector<bool> > ChannelStatus;//! + + public: + void Clear(); + void Clear(const Option_t*) {}; + + public: // Static constructor to be passed to the Detector Factory + static NPL::VDetector* Construct(); + ClassDef(TquadranMSQ25Physics,1) // quadranMSQ25Physics structure +}; + + +namespace quadranMSQ25_LOCAL +{ + double fSi_E( const TquadranMSQ25Data* EventData , const int i ); + double fSi_T( const TquadranMSQ25Data* EventData , const int i ); +} + +#endif diff --git a/NPSimulation/Core/MaterialManager.cc b/NPSimulation/Core/MaterialManager.cc index 8eb8dae1e..3536f16d2 100644 --- a/NPSimulation/Core/MaterialManager.cc +++ b/NPSimulation/Core/MaterialManager.cc @@ -729,6 +729,28 @@ G4Material* MaterialManager::GetMaterialFromLibrary(string Name, double density) return material; } + else if (Name == "GAGG") { + if (!density) + density = 6.63 * g / cm3; + G4Material* material = new G4Material("NPS_" + Name, density, 4); + material->AddElement(GetElementFromLibrary("Gd"), 3); + material->AddElement(GetElementFromLibrary("Al"), 2); + material->AddElement(GetElementFromLibrary("Ga"), 3); + material->AddElement(GetElementFromLibrary("O"), 12); + m_Material[Name] = material; + return material; + } + + else if (Name == "CeBr3") { + if (!density) + density = 5.2 * g / cm3; + G4Material* material = new G4Material("NPS_" + Name, density, 2); + material->AddElement(GetElementFromLibrary("Ce"), 1); + material->AddElement(GetElementFromLibrary("Br"), 3); + m_Material[Name] = material; + return material; + } + // else if (Name == "GAGG_Ce") { // if (!density) // density = 6.63 * g / cm3; diff --git a/NPSimulation/Detectors/AnnularS4/AnnularS4.cc b/NPSimulation/Detectors/AnnularS4/AnnularS4.cc new file mode 100644 index 000000000..07b3faddf --- /dev/null +++ b/NPSimulation/Detectors/AnnularS4/AnnularS4.cc @@ -0,0 +1,319 @@ +/***************************************************************************** + * Copyright (C) 2009-2016 this file is part of the NPTool Project * + * * + * For the licensing terms see $NPTOOL/Licence/NPTool_Licence * + * For the list of contributors see $NPTOOL/Licence/Contributors * + *****************************************************************************/ + +/***************************************************************************** + * Original Author: N. de Sereville contact address: deserevi@ipno.in2p3.fr * + * * + * Creation Date : 21/07/09 * + * Last update : 16/10/09 * + *---------------------------------------------------------------------------* + * Decription: Define the AnnularS4 detector from Micron * + * * + *---------------------------------------------------------------------------* + * Comment: * + * + 11/10/09: Change scorer philosophy, one scorer for the detector number * + * added (N. de Sereville) * + * * + *****************************************************************************/ + +// C++ headers +#include <cmath> +#include <sstream> +#include <string> + +// Geant4 +#include "G4Box.hh" +#include "G4Colour.hh" +#include "G4ExtrudedSolid.hh" +#include "G4Material.hh" +#include "G4MultiFunctionalDetector.hh" +#include "G4PVDivision.hh" +#include "G4PVPlacement.hh" +#include "G4RotationMatrix.hh" +#include "G4SDManager.hh" +#include "G4SubtractionSolid.hh" +#include "G4Transform3D.hh" +#include "G4Tubs.hh" +#include "G4VisAttributes.hh" + +// NPTool headers +#include "AnnularS4.hh" +#include "DSSDScorers.hh" +#include "InteractionScorers.hh" +#include "MaterialManager.hh" +#include "NPOptionManager.h" +#include "NPSDetectorFactory.hh" +#include "RootOutput.h" +#include "TAnnularS4Data.h" +// CLHEP +#include "CLHEP/Random/RandGauss.h" + +using namespace std; +using namespace CLHEP; +using namespace ANNULARS4; + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +AnnularS4::AnnularS4() { + m_Event = new TAnnularS4Data(); + m_LogicalDetector = 0; +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +AnnularS4::~AnnularS4() {} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +void AnnularS4::AddModule(G4double PosZ) { m_PosZ.push_back(PosZ); } + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +G4LogicalVolume* AnnularS4::ConstructVolume() { + + if (!m_LogicalDetector) { + G4Material* Silicon = MaterialManager::getInstance()->GetMaterialFromLibrary("Si"); + G4Material* Vacuum = MaterialManager::getInstance()->GetMaterialFromLibrary("Vacuum"); + //////////////////////////////////////////////////////////////// + ////////////// Starting Volume Definition ////////////////////// + //////////////////////////////////////////////////////////////// + // Name of the module + G4String Name = "AnnularS4"; + + // Building the PCB + // The PCB is a simple extruded volume from 8reference point + vector<G4TwoVector> polygon; + for (unsigned int i = 0; i < 4; i++) { + G4TwoVector Point(PCBPointsX[i], PCBPointsY[i]); + polygon.push_back(Point); + } + + // Mast volume containing all the detector + G4ExtrudedSolid* solidAnnularS4 = + new G4ExtrudedSolid(Name, polygon, PCBThickness * 0.5, G4TwoVector(0, 0), 1, G4TwoVector(0, 0), 1); + + // Definition of the volume containing the sensitive detector + m_LogicalDetector = new G4LogicalVolume(solidAnnularS4, Vacuum, Name, 0, 0, 0); + m_LogicalDetector->SetVisAttributes(G4VisAttributes::GetInvisible()); + + // PCB Base + G4ExtrudedSolid* solidPCBBase = + new G4ExtrudedSolid("PCBBase", polygon, PCBThickness * 0.5, G4TwoVector(0, 0), 1, G4TwoVector(0, 0), 1); + + // Wafer Shape to be substracted to the PCB + G4Tubs* solidWaferShape = new G4Tubs("WaferShape", 0, WaferOutterRadius, PCBThickness, 0 * deg, 360 * deg); + // G4Tubs* solidWaferShapeBase = new G4Tubs("WaferShape", 0, WaferOutterRadius, PCBThickness, 0 * deg, 360 * deg); + + // A no rotation matrix is always handy ;) + G4RotationMatrix* norotation = new G4RotationMatrix(); + // Rotation of the box that make the Si cut + // G4RotationMatrix* cutrotation = new G4RotationMatrix(G4ThreeVector(0, 0, 1), 45 * deg); + // G4ThreeVector cutposition1(80 * mm + WaferRCut, 0, 0); + // cutposition1.setPhi(45 * deg); + // G4Transform3D transform1(*cutrotation, cutposition1); + + // G4Box* solidCutout = new G4Box("cuttout", 80 * mm, 80 * mm, 80 * mm); + + // G4SubtractionSolid* solidWaferShape1 = + // new G4SubtractionSolid("WaferShape1", solidWaferShapeBase, solidCutout, transform1); + + // G4ThreeVector cutposition2(-80 * mm - WaferRCut, 0, 0); + // cutposition2.setPhi(-135 * deg); + // G4Transform3D transform2(*cutrotation, cutposition2); + // G4SubtractionSolid* solidWaferShape = + // new G4SubtractionSolid("WaferShape", solidWaferShape1, solidCutout, transform2); + + // PCB final + G4SubtractionSolid* solidPCB = new G4SubtractionSolid("AnnularS4_PCB1", solidPCBBase, solidWaferShape); + + G4LogicalVolume* logicPCB = new G4LogicalVolume(solidPCB, Vacuum, "AnnularS4_PCB", 0, 0, 0); + + new G4PVPlacement(G4Transform3D(*norotation, G4ThreeVector()), logicPCB, "AnnularS4_PCB", m_LogicalDetector, false, + 0); + + G4VisAttributes* PCBVisAtt = new G4VisAttributes(G4Colour(0.2, 0.5, 0.2)); + logicPCB->SetVisAttributes(PCBVisAtt); + + // Wafer itself + // G4Tubs* solidWaferBase = + G4Tubs* solidWafer = + new G4Tubs("Wafer", WaferInnerRadius, WaferOutterRadius, 0.5 * WaferThickness, 0 * deg, 360 * deg); + + // G4SubtractionSolid* solidWafer1 = new G4SubtractionSolid("Wafer1", solidWaferBase, solidCutout, transform1); + + // G4SubtractionSolid* solidWafer = new G4SubtractionSolid("Wafer", solidWafer1, solidCutout, transform2); + + G4LogicalVolume* logicWafer = new G4LogicalVolume(solidWafer, Silicon, "AnnularS4_Wafer", 0, 0, 0); + new G4PVPlacement(G4Transform3D(*norotation, G4ThreeVector()), logicWafer, "AnnularS4_Wafer", m_LogicalDetector, + false, 0); + + G4VisAttributes* SiVisAtt = new G4VisAttributes(G4Colour(0.3, 0.3, 0.3)); + logicWafer->SetVisAttributes(SiVisAtt); + + // Active Wafer + // G4Tubs* solidActiveWaferBase = new G4Tubs("ActiveWafer", ActiveWaferInnerRadius, ActiveWaferOutterRadius, + G4Tubs* solidActiveWafer = new G4Tubs("ActiveWafer", ActiveWaferInnerRadius, ActiveWaferOutterRadius, + 0.5 * WaferThickness, 0 * deg, 360 * deg); + + // G4ThreeVector activecutposition1(80 * mm + ActiveWaferRCut, 0, 0); + // activecutposition1.setPhi(45 * deg); + // G4Transform3D activetransform1(*cutrotation, activecutposition1); + + // G4SubtractionSolid* solidActiveWafer1 = + // new G4SubtractionSolid("ActiveWafer1", solidActiveWaferBase, solidCutout, activetransform1); + + // G4ThreeVector activecutposition2(-80 * mm - ActiveWaferRCut, 0, 0); + // activecutposition2.setPhi(-135 * deg); + // G4Transform3D activetransform2(*cutrotation, activecutposition2); + + // G4SubtractionSolid* solidActiveWafer = + // new G4SubtractionSolid("ActiveWafer", solidActiveWafer1, solidCutout, activetransform2); + + G4LogicalVolume* logicActiveWafer = + new G4LogicalVolume(solidActiveWafer, Silicon, "AnnularS4_ActiveWafer", 0, 0, 0); + new G4PVPlacement(G4Transform3D(*norotation, G4ThreeVector()), logicActiveWafer, "AnnularS4_ActiveWafer", + logicWafer, false, 0); + + logicActiveWafer->SetVisAttributes(SiVisAtt); + + // Set Silicon strip sensible + logicActiveWafer->SetSensitiveDetector(m_Scorer); + } + return m_LogicalDetector; +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +// Virtual Method of NPS::VDetector class + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +// Read stream at Configfile to pick-up parameters of detector (Position,...) +// Called in DetecorConstruction::ReadDetextorConfiguration Method +void AnnularS4::ReadConfiguration(NPL::InputParser parser) { + vector<NPL::InputBlock*> blocks = parser.GetAllBlocksWithToken("AnnularS4"); + cout << "//// " << blocks.size() << " detectors found " << endl; + + vector<string> token = {"Z"}; + + for (unsigned int i = 0; i < blocks.size(); i++) { + if (blocks[i]->HasTokenList(token)) { + double Z = blocks[i]->GetDouble("Z", "mm"); + AddModule(Z); + } + + else { + cout << "ERROR: check your input file formatting " << endl; + exit(1); + } + } +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +// Construct detector and inialise sensitive part. +// Called After DetecorConstruction::AddDetector Method +void AnnularS4::ConstructDetector(G4LogicalVolume* world) { + G4RotationMatrix* rotation = NULL; + G4ThreeVector position = G4ThreeVector(0, 0, 0); + + G4int NumberOfModule = m_PosZ.size(); + + for (G4int i = 0; i < NumberOfModule; i++) { + // translation to position the module + position = G4ThreeVector(0, 0, m_PosZ[i]); + + // Passage Matrix from Lab Referential to Module Referential + // Identity matrix by default + rotation = new G4RotationMatrix(); + if (position.z() < 0) + rotation->rotateX(180 * deg); + + new G4PVPlacement(G4Transform3D(*rotation, position), ConstructVolume(), "AnnularS4", world, false, i + 1); + } + + delete rotation; +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +// Connect the GaspardTrackingData class to the output TTree +// of the simulation +void AnnularS4::InitializeRootOutput() { + RootOutput* pAnalysis = RootOutput::getInstance(); + TTree* pTree = pAnalysis->GetTree(); + if (!pTree->FindBranch("AnnularS4")) { + pTree->Branch("AnnularS4", "TAnnularS4Data", &m_Event); + } + pTree->SetBranchAddress("AnnularS4", &m_Event); +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +// Read sensitive part and fill the Root tree. +// Called at in the EventAction::EndOfEventAvtion +void AnnularS4::ReadSensitive(const G4Event*) { + // Clear ROOT objects + m_Event->Clear(); + + DSSDScorers::PS_Annular* Scorer = (DSSDScorers::PS_Annular*)m_Scorer->GetPrimitive(0); + + // Loop on Silicon Sector Hit + unsigned int sizeSector = Scorer->GetSectorMult(); + for (unsigned int i = 0; i < sizeSector; i++) { + double Energy = Scorer->GetEnergyRing(i); + + if (Energy > EnergyThreshold) { + double Time = Scorer->GetTimeRing(i); + unsigned int DetNbr = Scorer->GetDetectorRing(i); + ; + unsigned int StripPhi = Scorer->GetStripSector(i); + + m_Event->SetS4_E_DetectorNbr(DetNbr); + m_Event->SetS4_E_StripNbr(StripPhi); + m_Event->SetS4_E_Energy(RandGauss::shoot(Energy, ResoEnergy)); + + m_Event->SetS4_T_DetectorNbr(DetNbr); + m_Event->SetS4_T_StripNbr(StripPhi); + m_Event->SetS4_T_Time(RandGauss::shoot(Time, ResoTime)); + } + } +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +// Initilize the Scorer use to read out the sensitive volume +void AnnularS4::InitializeScorers() { + bool already_exist = false; + // Associate Scorer + m_Scorer = CheckScorer("AnnularS4_Scorer", already_exist); + if (already_exist) + return; + + G4VPrimitiveScorer* AnnularScorer = + new DSSDScorers::PS_Annular("AnnularS4_Scorer", 2, ActiveWaferInnerRadius, ActiveWaferOutterRadius, + -8 * 22.5 * deg, // MUST2 campaign 2009, See: Phd Sandra Giron + +8 * 22.5 * deg, NbrRingStrips, NbrSectorStrips, NbQuadrant); + + m_Scorer->RegisterPrimitive(AnnularScorer); + G4VPrimitiveScorer* InteractionScorer = new InteractionScorers::PS_Interactions("InteractionAnnularS4", ms_InterCoord, 2); + m_Scorer->RegisterPrimitive(InteractionScorer); + // Add All Scorer to the Global Scorer Manager + G4SDManager::GetSDMpointer()->AddNewDetector(m_Scorer); +} +//////////////////////////////////////////////////////////////////////////////// +// Construct Method to be pass to the DetectorFactory // +//////////////////////////////////////////////////////////////////////////////// +NPS::VDetector* AnnularS4::Construct() { return (NPS::VDetector*)new AnnularS4(); } + +//////////////////////////////////////////////////////////////////////////////// +// Registering the construct method to the factory // +//////////////////////////////////////////////////////////////////////////////// +extern "C" { +class proxy_nps_annulars4 { + public: + proxy_nps_annulars4() { + NPS::DetectorFactory::getInstance()->AddToken("AnnularS4", "AnnularS4"); + NPS::DetectorFactory::getInstance()->AddDetector("AnnularS4", AnnularS4::Construct); + } +}; + +proxy_nps_annulars4 p_nps_annulars4; +} + diff --git a/NPSimulation/Detectors/AnnularS4/AnnularS4.hh b/NPSimulation/Detectors/AnnularS4/AnnularS4.hh new file mode 100644 index 000000000..2c7024a36 --- /dev/null +++ b/NPSimulation/Detectors/AnnularS4/AnnularS4.hh @@ -0,0 +1,150 @@ +#ifndef AnnularS4_h +#define AnnularS4_h 1 +/***************************************************************************** + * Copyright (C) 2009-2016 this file is part of the NPTool Project * + * * + * For the licensing terms see $NPTOOL/Licence/NPTool_Licence * + * For the list of contributors see $NPTOOL/Licence/Contributors * + *****************************************************************************/ + +/***************************************************************************** + * Original Author: N. de Sereville contact address: deserevi@ipno.in2p3.fr * + * * + * Creation Date : 21/07/09 * + * Last update : 11/10/09 * + *---------------------------------------------------------------------------* + * Decription: Define the AnnularS4 detector from Micron * + * * + *---------------------------------------------------------------------------* + * Comment: * + * + 11/10/09: Change scorer philosophy, one scorer for the detector number * + * added (N. de Sereville) * + * * + *****************************************************************************/ + +// C++ headers +#include <vector> +using namespace std; +using namespace CLHEP; + +// NPTool header +#include "NPSVDetector.hh" +#include "NPInputParser.h" +// NPTool - ROOT headers +#include "TAnnularS4Data.h" + +// Geant4 +#include "G4MultiFunctionalDetector.hh" +#include "G4LogicalVolume.hh" + +class AnnularS4 : public NPS::VDetector{ + //////////////////////////////////////////////////// + /////// Default Constructor and Destructor ///////// + //////////////////////////////////////////////////// +public: + AnnularS4(); + virtual ~AnnularS4(); + + //////////////////////////////////////////////////// + //////// Specific Function of this Class /////////// + //////////////////////////////////////////////////// +public: + // By Position Method + void AddModule(G4double PosZ); + + // Produce the logical volume of the detector + G4LogicalVolume* ConstructVolume(); + +private: + G4LogicalVolume* m_LogicalDetector; + + //////////////////////////////////////////////////// + //// Inherite from GaspardTrackerModule class ///// + //////////////////////////////////////////////////// +public: + // Read stream at Configfile to pick-up parameters of detector (Position,...) + // Called in DetecorConstruction::ReadDetextorConfiguration Method + void ReadConfiguration(NPL::InputParser); + + // Construct detector and inialise sensitive part. + // Called After DetecorConstruction::AddDetector Method + void ConstructDetector(G4LogicalVolume* world); + + // Add Detector branch to the EventTree. + // Called After DetecorConstruction::AddDetector Method + void InitializeRootOutput(); + + // Initialize all scorers necessary for the detector + void InitializeScorers(); + + // Read sensitive part and fill the Root tree. + // Called at in the EventAction::EndOfEventAvtion + void ReadSensitive(const G4Event* event); + + + //////////////////////////////////////////////////// + ///////////Event class to store Data//////////////// + //////////////////////////////////////////////////// +private: + TAnnularS4Data* m_Event; + + +private: + // Scorer + G4MultiFunctionalDetector* m_Scorer; + + + //////////////////////////////////////////////////// + ///////////////Private intern Data////////////////// + //////////////////////////////////////////////////// +private: + // Used for "By Point Definition" + vector<G4double> m_PosZ; + + public: + static NPS::VDetector* Construct(); + + + +}; + + + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +namespace ANNULARS4{ + // Energy/Time resolutions for the different layers + const G4double ResoTime = 0.106382979 ;// = 250 ps // unchecked // Unit is ns/2.35 + const G4double EnergyThreshold = 0.300 ;// = 300 keV // unchecked + const G4double ResoEnergy = 0.0149 ; // 0.0217 // unchecked + + // PCB + const G4double PCBPointsX[4]={-70,70,70,-70}; // bricoled + const G4double PCBPointsY[4]={70,70,-70,-70}; // bricoled + const G4double PCBThickness=3.2*mm; // unchecked + const G4double PCBInnerRadius=0*mm; // unchecked + // Wafer + const G4double WaferOutterRadius = 65.05*mm; + const G4double WaferInnerRadius = 5*mm; + const G4double WaferThickness = 500*micrometer; // unchecked + const G4double WaferRCut = 45.5*mm; // unchecked + const G4double ActiveWaferOutterRadius = 62.49*mm; + const G4double ActiveWaferInnerRadius = 7.5*mm; + const G4double AluStripThickness = 0.3*micrometer; + const G4double ActiveWaferRCut = 44.5*mm; // unchecked + + // Characteristics + const G4int NbrRingStrips = 1; // unsure + const G4int NbrSectorStrips = 128; + const G4int NbQuadrant = 1; // unsure + + // total WaferLength + const G4double Length = AluStripThickness*2+WaferThickness; + + // Starting at the front and going in direction of third stage + const G4double AluStripFront_PosZ = Length* -0.5 + 0.5*AluStripThickness; // unchecked + const G4double Silicon_PosZ = AluStripFront_PosZ + 0.5*AluStripThickness + 0.5*WaferThickness; // unchecked + const G4double AluStripBack_PosZ = Silicon_PosZ + 0.5*WaferThickness + 0.5*AluStripThickness; // unchecked + +} + +#endif diff --git a/NPSimulation/Detectors/AnnularS4/CMakeLists.txt b/NPSimulation/Detectors/AnnularS4/CMakeLists.txt new file mode 100644 index 000000000..ef17c8397 --- /dev/null +++ b/NPSimulation/Detectors/AnnularS4/CMakeLists.txt @@ -0,0 +1,2 @@ +add_library(NPSAnnularS4 SHARED AnnularS4.cc) +target_link_libraries(NPSAnnularS4 NPSCore ${ROOT_LIBRARIES} ${Geant4_LIBRARIES} ${NPLib_LIBRARIES} -lNPAnnularS4) diff --git a/NPSimulation/Detectors/CeBr3/CMakeLists.txt b/NPSimulation/Detectors/CeBr3/CMakeLists.txt new file mode 100644 index 000000000..ba27cd44e --- /dev/null +++ b/NPSimulation/Detectors/CeBr3/CMakeLists.txt @@ -0,0 +1,2 @@ +add_library(NPSCeBr3 SHARED CeBr3.cc) +target_link_libraries(NPSCeBr3 NPSCore ${ROOT_LIBRARIES} ${Geant4_LIBRARIES} ${NPLib_LIBRARIES} -lNPCeBr3) diff --git a/NPSimulation/Detectors/CeBr3/CeBr3.cc b/NPSimulation/Detectors/CeBr3/CeBr3.cc new file mode 100644 index 000000000..abcfa046b --- /dev/null +++ b/NPSimulation/Detectors/CeBr3/CeBr3.cc @@ -0,0 +1,292 @@ +/***************************************************************************** + * Copyright (C) 2009-2023 this file is part of the NPTool Project * + * * + * For the licensing terms see $NPTOOL/Licence/NPTool_Licence * + * For the list of contributors see $NPTOOL/Licence/Contributors * + *****************************************************************************/ + +/***************************************************************************** + * Original Author: Leo Plagnol contact address: plagnol@ijclab.in2p3.fr * + * * + * Creation Date : December 2023 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class describe CeBr3 simulation * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + *****************************************************************************/ + +// C++ headers +#include <sstream> +#include <cmath> +#include <limits> +//G4 Geometry object +#include "G4Tubs.hh" +#include "G4Box.hh" + +//G4 sensitive +#include "G4SDManager.hh" +#include "G4MultiFunctionalDetector.hh" + +//G4 various object +#include "G4Material.hh" +#include "G4Transform3D.hh" +#include "G4PVPlacement.hh" +#include "G4VisAttributes.hh" +#include "G4Colour.hh" + +// NPTool header +#include "CeBr3.hh" +#include "CalorimeterScorers.hh" +#include "InteractionScorers.hh" +#include "RootOutput.h" +#include "MaterialManager.hh" +#include "NPSDetectorFactory.hh" +#include "NPOptionManager.h" +#include "NPSHitsMap.hh" +// CLHEP header +#include "CLHEP/Random/RandGauss.h" + +using namespace std; +using namespace CLHEP; + + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +namespace CeBr3_NS{ + // Energy and time Resolution + const double EnergyThreshold = 0.1*MeV; + const double ResoTime = 19*ns ; + const double ResoEnergy = 3.8*keV ; + const double Radius = 50*mm ; + const double Width = 100*mm ; + const double Thickness = 300*mm ; + const string Material = "CeBr3"; +} +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +// CeBr3 Specific Method +CeBr3::CeBr3(){ + m_Event = new TCeBr3Data() ; + m_CeBr3Scorer = 0; + m_SquareDetector = 0; + m_CylindricalDetector = 0; + + + // RGB Color + Transparency + m_VisSquare = new G4VisAttributes(G4Colour(1, 0.5, 0, 0.5)); + m_VisCylinder = new G4VisAttributes(G4Colour(1, 0.5, 0, 0.5)); + +} + +CeBr3::~CeBr3(){ +} +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +void CeBr3::AddDetector(G4ThreeVector POS, string Shape){ + // Convert the POS value to R theta Phi as Spherical coordinate is easier in G4 + m_R.push_back(POS.mag()); + m_Theta.push_back(POS.theta()); + m_Phi.push_back(POS.phi()); + m_Shape.push_back(Shape); +} + + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +void CeBr3::AddDetector(double R, double Theta, double Phi, string Shape){ + m_R.push_back(R); + m_Theta.push_back(Theta); + m_Phi.push_back(Phi); + m_Shape.push_back(Shape); +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +G4LogicalVolume* CeBr3::BuildSquareDetector(){ + if(!m_SquareDetector){ + G4Box* box = new G4Box("CeBr3_Box",CeBr3_NS::Width*0.5, + CeBr3_NS::Width*0.5,CeBr3_NS::Thickness*0.5); + + G4Material* DetectorMaterial = MaterialManager::getInstance()->GetMaterialFromLibrary(CeBr3_NS::Material); + m_SquareDetector = new G4LogicalVolume(box,DetectorMaterial,"logic_CeBr3_Box",0,0,0); + m_SquareDetector->SetVisAttributes(m_VisSquare); + m_SquareDetector->SetSensitiveDetector(m_CeBr3Scorer); + } + return m_SquareDetector; +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +G4LogicalVolume* CeBr3::BuildCylindricalDetector(){ + if(!m_CylindricalDetector){ + G4Tubs* tub = new G4Tubs("CeBr3_Cyl",0,CeBr3_NS::Radius,CeBr3_NS::Thickness*0.5,0,360*deg); + + G4Material* DetectorMaterial = MaterialManager::getInstance()->GetMaterialFromLibrary(CeBr3_NS::Material); + m_CylindricalDetector = new G4LogicalVolume(tub,DetectorMaterial,"logic_CeBr3_tub",0,0,0); + m_CylindricalDetector->SetVisAttributes(m_VisSquare); + m_CylindricalDetector->SetSensitiveDetector(m_CeBr3Scorer); + + } + return m_CylindricalDetector; +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +// Virtual Method of NPS::VDetector class + +// Read stream at Configfile to pick-up parameters of detector (Position,...) +// Called in DetecorConstruction::ReadDetextorConfiguration Method +void CeBr3::ReadConfiguration(NPL::InputParser parser){ + vector<NPL::InputBlock*> blocks = parser.GetAllBlocksWithToken("CeBr3"); + if(NPOptionManager::getInstance()->GetVerboseLevel()) + cout << "//// " << blocks.size() << " detectors found " << endl; + + vector<string> cart = {"POS","Shape"}; + vector<string> sphe = {"R","Theta","Phi","Shape"}; + + for(unsigned int i = 0 ; i < blocks.size() ; i++){ + if(blocks[i]->HasTokenList(cart)){ + if(NPOptionManager::getInstance()->GetVerboseLevel()) + cout << endl << "//// CeBr3 " << i+1 << endl; + + G4ThreeVector Pos = NPS::ConvertVector(blocks[i]->GetTVector3("POS","mm")); + string Shape = blocks[i]->GetString("Shape"); + AddDetector(Pos,Shape); + } + else if(blocks[i]->HasTokenList(sphe)){ + if(NPOptionManager::getInstance()->GetVerboseLevel()) + cout << endl << "//// CeBr3 " << i+1 << endl; + double R = blocks[i]->GetDouble("R","mm"); + double Theta = blocks[i]->GetDouble("Theta","deg"); + double Phi = blocks[i]->GetDouble("Phi","deg"); + string Shape = blocks[i]->GetString("Shape"); + AddDetector(R,Theta,Phi,Shape); + } + else{ + cout << "ERROR: check your input file formatting " << endl; + exit(1); + } + } +} + + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... + +// Construct detector and inialise sensitive part. +// Called After DetecorConstruction::AddDetector Method +void CeBr3::ConstructDetector(G4LogicalVolume* world){ + for (unsigned short i = 0 ; i < m_R.size() ; i++) { + + G4double wX = m_R[i] * sin(m_Theta[i] ) * cos(m_Phi[i] ) ; + G4double wY = m_R[i] * sin(m_Theta[i] ) * sin(m_Phi[i] ) ; + G4double wZ = m_R[i] * cos(m_Theta[i] ) ; + G4ThreeVector Det_pos = G4ThreeVector(wX, wY, wZ) ; + // So the face of the detector is at R instead of the middle + Det_pos+=Det_pos.unit()*CeBr3_NS::Thickness*0.5; + // Building Detector reference frame + G4double ii = cos(m_Theta[i]) * cos(m_Phi[i]); + G4double jj = cos(m_Theta[i]) * sin(m_Phi[i]); + G4double kk = -sin(m_Theta[i]); + G4ThreeVector Y(ii,jj,kk); + G4ThreeVector w = Det_pos.unit(); + G4ThreeVector u = w.cross(Y); + G4ThreeVector v = w.cross(u); + v = v.unit(); + u = u.unit(); + + G4RotationMatrix* Rot = new G4RotationMatrix(u,v,w); + + if(m_Shape[i] == "Cylindrical"){ + new G4PVPlacement(G4Transform3D(*Rot,Det_pos), + BuildCylindricalDetector(), + "CeBr3",world,false,i+1); + } + + else if(m_Shape[i] == "Square"){ + new G4PVPlacement(G4Transform3D(*Rot,Det_pos), + BuildSquareDetector(), + "CeBr3",world,false,i+1); + } + } +} +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +// Add Detector branch to the EventTree. +// Called After DetecorConstruction::AddDetector Method +void CeBr3::InitializeRootOutput(){ + RootOutput *pAnalysis = RootOutput::getInstance(); + TTree *pTree = pAnalysis->GetTree(); + if(!pTree->FindBranch("CeBr3")){ + pTree->Branch("CeBr3", "TCeBr3Data", &m_Event) ; + } + pTree->SetBranchAddress("CeBr3", &m_Event) ; +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +// Read sensitive part and fill the Root tree. +// Called at in the EventAction::EndOfEventAvtion +void CeBr3::ReadSensitive(const G4Event* ){ + m_Event->Clear(); + + /////////// + // Calorimeter scorer + CalorimeterScorers::PS_Calorimeter* Scorer= (CalorimeterScorers::PS_Calorimeter*) m_CeBr3Scorer->GetPrimitive(0); + + unsigned int size = Scorer->GetMult(); + for(unsigned int i = 0 ; i < size ; i++){ + vector<unsigned int> level = Scorer->GetLevel(i); + double Energy = RandGauss::shoot(Scorer->GetEnergy(i),CeBr3_NS::ResoEnergy); + if(Energy>CeBr3_NS::EnergyThreshold){ + double Time = RandGauss::shoot(Scorer->GetTime(i),CeBr3_NS::ResoTime); + int DetectorNbr = level[0]; + m_Event->SetEnergy(DetectorNbr,Energy); + m_Event->SetTime(DetectorNbr,Time); + } + } +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//////////////////////////////////////////////////////////////// +void CeBr3::InitializeScorers() { + // This check is necessary in case the geometry is reloaded + bool already_exist = false; + m_CeBr3Scorer = CheckScorer("CeBr3Scorer",already_exist) ; + + if(already_exist) + return ; + + // Otherwise the scorer is initialised + vector<int> level; level.push_back(0); + G4VPrimitiveScorer* Calorimeter= new CalorimeterScorers::PS_Calorimeter("Calorimeter",level, 0) ; + G4VPrimitiveScorer* Interaction= new InteractionScorers::PS_Interactions("Interaction",ms_InterCoord, 0) ; + //and register it to the multifunctionnal detector + m_CeBr3Scorer->RegisterPrimitive(Calorimeter); + m_CeBr3Scorer->RegisterPrimitive(Interaction); + G4SDManager::GetSDMpointer()->AddNewDetector(m_CeBr3Scorer) ; +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//////////////////////////////////////////////////////////////////////////////// +// Construct Method to be pass to the DetectorFactory // +//////////////////////////////////////////////////////////////////////////////// +NPS::VDetector* CeBr3::Construct(){ + return (NPS::VDetector*) new CeBr3(); +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//////////////////////////////////////////////////////////////////////////////// +// Registering the construct method to the factory // +//////////////////////////////////////////////////////////////////////////////// +extern"C" { + class proxy_nps_CeBr3{ + public: + proxy_nps_CeBr3(){ + NPS::DetectorFactory::getInstance()->AddToken("CeBr3","CeBr3"); + NPS::DetectorFactory::getInstance()->AddDetector("CeBr3",CeBr3::Construct); + } + }; + + proxy_nps_CeBr3 p_nps_CeBr3; +} diff --git a/NPSimulation/Detectors/CeBr3/CeBr3.hh b/NPSimulation/Detectors/CeBr3/CeBr3.hh new file mode 100644 index 000000000..638fa0229 --- /dev/null +++ b/NPSimulation/Detectors/CeBr3/CeBr3.hh @@ -0,0 +1,117 @@ +#ifndef CeBr3_h +#define CeBr3_h 1 +/***************************************************************************** + * Copyright (C) 2009-2023 this file is part of the NPTool Project * + * * + * For the licensing terms see $NPTOOL/Licence/NPTool_Licence * + * For the list of contributors see $NPTOOL/Licence/Contributors * + *****************************************************************************/ + +/***************************************************************************** + * Original Author: Leo Plagnol contact address: plagnol@ijclab.in2p3.fr * + * * + * Creation Date : December 2023 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class describe CeBr3 simulation * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + *****************************************************************************/ + +// C++ header +#include <string> +#include <vector> +using namespace std; + +// G4 headers +#include "G4ThreeVector.hh" +#include "G4RotationMatrix.hh" +#include "G4LogicalVolume.hh" +#include "G4MultiFunctionalDetector.hh" + +// NPTool header +#include "NPSVDetector.hh" +#include "TCeBr3Data.h" +#include "NPInputParser.h" + +class CeBr3 : public NPS::VDetector{ + //////////////////////////////////////////////////// + /////// Default Constructor and Destructor ///////// + //////////////////////////////////////////////////// + public: + CeBr3() ; + virtual ~CeBr3() ; + + //////////////////////////////////////////////////// + /////// Specific Function of this Class /////////// + //////////////////////////////////////////////////// + public: + // Cartesian + void AddDetector(G4ThreeVector POS, string Shape); + // Spherical + void AddDetector(double R,double Theta,double Phi,string Shape); + + + G4LogicalVolume* BuildSquareDetector(); + G4LogicalVolume* BuildCylindricalDetector(); + + private: + G4LogicalVolume* m_SquareDetector; + G4LogicalVolume* m_CylindricalDetector; + + //////////////////////////////////////////////////// + ////// Inherite from NPS::VDetector class ///////// + //////////////////////////////////////////////////// + public: + // Read stream at Configfile to pick-up parameters of detector (Position,...) + // Called in DetecorConstruction::ReadDetextorConfiguration Method + void ReadConfiguration(NPL::InputParser) ; + + // Construct detector and inialise sensitive part. + // Called After DetecorConstruction::AddDetector Method + void ConstructDetector(G4LogicalVolume* world) ; + + // Add Detector branch to the EventTree. + // Called After DetecorConstruction::AddDetector Method + void InitializeRootOutput() ; + + // Read sensitive part and fill the Root tree. + // Called at in the EventAction::EndOfEventAvtion + void ReadSensitive(const G4Event* event) ; + + public: // Scorer + // Initialize all Scorer used by the MUST2Array + void InitializeScorers() ; + + // Associated Scorer + G4MultiFunctionalDetector* m_CeBr3Scorer ; + //////////////////////////////////////////////////// + ///////////Event class to store Data//////////////// + //////////////////////////////////////////////////// + private: + TCeBr3Data* m_Event ; + + //////////////////////////////////////////////////// + ///////////////Private intern Data////////////////// + //////////////////////////////////////////////////// + private: // Geometry + // Detector Coordinate + vector<double> m_R; + vector<double> m_Theta; + vector<double> m_Phi; + + // Shape type + vector<string> m_Shape ; + + // Visualisation Attribute + G4VisAttributes* m_VisSquare; + G4VisAttributes* m_VisCylinder; + + // Needed for dynamic loading of the library + public: + static NPS::VDetector* Construct(); +}; +#endif diff --git a/NPSimulation/Detectors/GeLi/CMakeLists.txt b/NPSimulation/Detectors/GeLi/CMakeLists.txt new file mode 100644 index 000000000..a4d8159dc --- /dev/null +++ b/NPSimulation/Detectors/GeLi/CMakeLists.txt @@ -0,0 +1,2 @@ +add_library(NPSGeLi SHARED GeLi.cc) +target_link_libraries(NPSGeLi NPSCore ${ROOT_LIBRARIES} ${Geant4_LIBRARIES} ${NPLib_LIBRARIES} -lNPGeLi) diff --git a/NPSimulation/Detectors/GeLi/GeLi.cc b/NPSimulation/Detectors/GeLi/GeLi.cc new file mode 100644 index 000000000..bf9bca094 --- /dev/null +++ b/NPSimulation/Detectors/GeLi/GeLi.cc @@ -0,0 +1,292 @@ +/***************************************************************************** + * Copyright (C) 2009-2023 this file is part of the NPTool Project * + * * + * For the licensing terms see $NPTOOL/Licence/NPTool_Licence * + * For the list of contributors see $NPTOOL/Licence/Contributors * + *****************************************************************************/ + +/***************************************************************************** + * Original Author: Leo Plagnol contact address: plagnol@ijclab.in2p3.fr * + * * + * Creation Date : December 2023 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class describe GeLi simulation * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + *****************************************************************************/ + +// C++ headers +#include <sstream> +#include <cmath> +#include <limits> +//G4 Geometry object +#include "G4Tubs.hh" +#include "G4Box.hh" + +//G4 sensitive +#include "G4SDManager.hh" +#include "G4MultiFunctionalDetector.hh" + +//G4 various object +#include "G4Material.hh" +#include "G4Transform3D.hh" +#include "G4PVPlacement.hh" +#include "G4VisAttributes.hh" +#include "G4Colour.hh" + +// NPTool header +#include "GeLi.hh" +#include "CalorimeterScorers.hh" +#include "InteractionScorers.hh" +#include "RootOutput.h" +#include "MaterialManager.hh" +#include "NPSDetectorFactory.hh" +#include "NPOptionManager.h" +#include "NPSHitsMap.hh" +// CLHEP header +#include "CLHEP/Random/RandGauss.h" + +using namespace std; +using namespace CLHEP; + + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +namespace GeLi_NS{ + // Energy and time Resolution + const double EnergyThreshold = 0.1*MeV; + const double ResoTime = 4.5*ns ; + const double ResoEnergy = 2.0*keV ; + const double Radius = 50*mm ; + const double Width = 100*mm ; + const double Thickness = 300*mm ; + const string Material = "Germanium"; +} +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +// GeLi Specific Method +GeLi::GeLi(){ + m_Event = new TGeLiData() ; + m_GeLiScorer = 0; + m_SquareDetector = 0; + m_CylindricalDetector = 0; + + + // RGB Color + Transparency + m_VisSquare = new G4VisAttributes(G4Colour(1, 1, 0, 0.5)); + m_VisCylinder = new G4VisAttributes(G4Colour(1, 1, 0, 0.5)); + +} + +GeLi::~GeLi(){ +} +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +void GeLi::AddDetector(G4ThreeVector POS, string Shape){ + // Convert the POS value to R theta Phi as Spherical coordinate is easier in G4 + m_R.push_back(POS.mag()); + m_Theta.push_back(POS.theta()); + m_Phi.push_back(POS.phi()); + m_Shape.push_back(Shape); +} + + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +void GeLi::AddDetector(double R, double Theta, double Phi, string Shape){ + m_R.push_back(R); + m_Theta.push_back(Theta); + m_Phi.push_back(Phi); + m_Shape.push_back(Shape); +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +G4LogicalVolume* GeLi::BuildSquareDetector(){ + if(!m_SquareDetector){ + G4Box* box = new G4Box("GeLi_Box",GeLi_NS::Width*0.5, + GeLi_NS::Width*0.5,GeLi_NS::Thickness*0.5); + + G4Material* DetectorMaterial = MaterialManager::getInstance()->GetMaterialFromLibrary(GeLi_NS::Material); + m_SquareDetector = new G4LogicalVolume(box,DetectorMaterial,"logic_GeLi_Box",0,0,0); + m_SquareDetector->SetVisAttributes(m_VisSquare); + m_SquareDetector->SetSensitiveDetector(m_GeLiScorer); + } + return m_SquareDetector; +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +G4LogicalVolume* GeLi::BuildCylindricalDetector(){ + if(!m_CylindricalDetector){ + G4Tubs* tub = new G4Tubs("GeLi_Cyl",0,GeLi_NS::Radius,GeLi_NS::Thickness*0.5,0,360*deg); + + G4Material* DetectorMaterial = MaterialManager::getInstance()->GetMaterialFromLibrary(GeLi_NS::Material); + m_CylindricalDetector = new G4LogicalVolume(tub,DetectorMaterial,"logic_GeLi_tub",0,0,0); + m_CylindricalDetector->SetVisAttributes(m_VisSquare); + m_CylindricalDetector->SetSensitiveDetector(m_GeLiScorer); + + } + return m_CylindricalDetector; +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +// Virtual Method of NPS::VDetector class + +// Read stream at Configfile to pick-up parameters of detector (Position,...) +// Called in DetecorConstruction::ReadDetextorConfiguration Method +void GeLi::ReadConfiguration(NPL::InputParser parser){ + vector<NPL::InputBlock*> blocks = parser.GetAllBlocksWithToken("GeLi"); + if(NPOptionManager::getInstance()->GetVerboseLevel()) + cout << "//// " << blocks.size() << " detectors found " << endl; + + vector<string> cart = {"POS","Shape"}; + vector<string> sphe = {"R","Theta","Phi","Shape"}; + + for(unsigned int i = 0 ; i < blocks.size() ; i++){ + if(blocks[i]->HasTokenList(cart)){ + if(NPOptionManager::getInstance()->GetVerboseLevel()) + cout << endl << "//// GeLi " << i+1 << endl; + + G4ThreeVector Pos = NPS::ConvertVector(blocks[i]->GetTVector3("POS","mm")); + string Shape = blocks[i]->GetString("Shape"); + AddDetector(Pos,Shape); + } + else if(blocks[i]->HasTokenList(sphe)){ + if(NPOptionManager::getInstance()->GetVerboseLevel()) + cout << endl << "//// GeLi " << i+1 << endl; + double R = blocks[i]->GetDouble("R","mm"); + double Theta = blocks[i]->GetDouble("Theta","deg"); + double Phi = blocks[i]->GetDouble("Phi","deg"); + string Shape = blocks[i]->GetString("Shape"); + AddDetector(R,Theta,Phi,Shape); + } + else{ + cout << "ERROR: check your input file formatting " << endl; + exit(1); + } + } +} + + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... + +// Construct detector and inialise sensitive part. +// Called After DetecorConstruction::AddDetector Method +void GeLi::ConstructDetector(G4LogicalVolume* world){ + for (unsigned short i = 0 ; i < m_R.size() ; i++) { + + G4double wX = m_R[i] * sin(m_Theta[i] ) * cos(m_Phi[i] ) ; + G4double wY = m_R[i] * sin(m_Theta[i] ) * sin(m_Phi[i] ) ; + G4double wZ = m_R[i] * cos(m_Theta[i] ) ; + G4ThreeVector Det_pos = G4ThreeVector(wX, wY, wZ) ; + // So the face of the detector is at R instead of the middle + Det_pos+=Det_pos.unit()*GeLi_NS::Thickness*0.5; + // Building Detector reference frame + G4double ii = cos(m_Theta[i]) * cos(m_Phi[i]); + G4double jj = cos(m_Theta[i]) * sin(m_Phi[i]); + G4double kk = -sin(m_Theta[i]); + G4ThreeVector Y(ii,jj,kk); + G4ThreeVector w = Det_pos.unit(); + G4ThreeVector u = w.cross(Y); + G4ThreeVector v = w.cross(u); + v = v.unit(); + u = u.unit(); + + G4RotationMatrix* Rot = new G4RotationMatrix(u,v,w); + + if(m_Shape[i] == "Cylindrical"){ + new G4PVPlacement(G4Transform3D(*Rot,Det_pos), + BuildCylindricalDetector(), + "GeLi",world,false,i+1); + } + + else if(m_Shape[i] == "Square"){ + new G4PVPlacement(G4Transform3D(*Rot,Det_pos), + BuildSquareDetector(), + "GeLi",world,false,i+1); + } + } +} +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +// Add Detector branch to the EventTree. +// Called After DetecorConstruction::AddDetector Method +void GeLi::InitializeRootOutput(){ + RootOutput *pAnalysis = RootOutput::getInstance(); + TTree *pTree = pAnalysis->GetTree(); + if(!pTree->FindBranch("GeLi")){ + pTree->Branch("GeLi", "TGeLiData", &m_Event) ; + } + pTree->SetBranchAddress("GeLi", &m_Event) ; +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +// Read sensitive part and fill the Root tree. +// Called at in the EventAction::EndOfEventAvtion +void GeLi::ReadSensitive(const G4Event* ){ + m_Event->Clear(); + + /////////// + // Calorimeter scorer + CalorimeterScorers::PS_Calorimeter* Scorer= (CalorimeterScorers::PS_Calorimeter*) m_GeLiScorer->GetPrimitive(0); + + unsigned int size = Scorer->GetMult(); + for(unsigned int i = 0 ; i < size ; i++){ + vector<unsigned int> level = Scorer->GetLevel(i); + double Energy = RandGauss::shoot(Scorer->GetEnergy(i),GeLi_NS::ResoEnergy); + if(Energy>GeLi_NS::EnergyThreshold){ + double Time = RandGauss::shoot(Scorer->GetTime(i),GeLi_NS::ResoTime); + int DetectorNbr = level[0]; + m_Event->SetEnergy(DetectorNbr,Energy); + m_Event->SetTime(DetectorNbr,Time); + } + } +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//////////////////////////////////////////////////////////////// +void GeLi::InitializeScorers() { + // This check is necessary in case the geometry is reloaded + bool already_exist = false; + m_GeLiScorer = CheckScorer("GeLiScorer",already_exist) ; + + if(already_exist) + return ; + + // Otherwise the scorer is initialised + vector<int> level; level.push_back(0); + G4VPrimitiveScorer* Calorimeter= new CalorimeterScorers::PS_Calorimeter("Calorimeter",level, 0) ; + G4VPrimitiveScorer* Interaction= new InteractionScorers::PS_Interactions("Interaction",ms_InterCoord, 0) ; + //and register it to the multifunctionnal detector + m_GeLiScorer->RegisterPrimitive(Calorimeter); + m_GeLiScorer->RegisterPrimitive(Interaction); + G4SDManager::GetSDMpointer()->AddNewDetector(m_GeLiScorer) ; +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//////////////////////////////////////////////////////////////////////////////// +// Construct Method to be pass to the DetectorFactory // +//////////////////////////////////////////////////////////////////////////////// +NPS::VDetector* GeLi::Construct(){ + return (NPS::VDetector*) new GeLi(); +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//////////////////////////////////////////////////////////////////////////////// +// Registering the construct method to the factory // +//////////////////////////////////////////////////////////////////////////////// +extern"C" { + class proxy_nps_GeLi{ + public: + proxy_nps_GeLi(){ + NPS::DetectorFactory::getInstance()->AddToken("GeLi","GeLi"); + NPS::DetectorFactory::getInstance()->AddDetector("GeLi",GeLi::Construct); + } + }; + + proxy_nps_GeLi p_nps_GeLi; +} diff --git a/NPSimulation/Detectors/GeLi/GeLi.hh b/NPSimulation/Detectors/GeLi/GeLi.hh new file mode 100644 index 000000000..c88560f39 --- /dev/null +++ b/NPSimulation/Detectors/GeLi/GeLi.hh @@ -0,0 +1,117 @@ +#ifndef GeLi_h +#define GeLi_h 1 +/***************************************************************************** + * Copyright (C) 2009-2023 this file is part of the NPTool Project * + * * + * For the licensing terms see $NPTOOL/Licence/NPTool_Licence * + * For the list of contributors see $NPTOOL/Licence/Contributors * + *****************************************************************************/ + +/***************************************************************************** + * Original Author: Leo Plagnol contact address: plagnol@ijclab.in2p3.fr * + * * + * Creation Date : December 2023 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class describe GeLi simulation * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + *****************************************************************************/ + +// C++ header +#include <string> +#include <vector> +using namespace std; + +// G4 headers +#include "G4ThreeVector.hh" +#include "G4RotationMatrix.hh" +#include "G4LogicalVolume.hh" +#include "G4MultiFunctionalDetector.hh" + +// NPTool header +#include "NPSVDetector.hh" +#include "TGeLiData.h" +#include "NPInputParser.h" + +class GeLi : public NPS::VDetector{ + //////////////////////////////////////////////////// + /////// Default Constructor and Destructor ///////// + //////////////////////////////////////////////////// + public: + GeLi() ; + virtual ~GeLi() ; + + //////////////////////////////////////////////////// + /////// Specific Function of this Class /////////// + //////////////////////////////////////////////////// + public: + // Cartesian + void AddDetector(G4ThreeVector POS, string Shape); + // Spherical + void AddDetector(double R,double Theta,double Phi,string Shape); + + + G4LogicalVolume* BuildSquareDetector(); + G4LogicalVolume* BuildCylindricalDetector(); + + private: + G4LogicalVolume* m_SquareDetector; + G4LogicalVolume* m_CylindricalDetector; + + //////////////////////////////////////////////////// + ////// Inherite from NPS::VDetector class ///////// + //////////////////////////////////////////////////// + public: + // Read stream at Configfile to pick-up parameters of detector (Position,...) + // Called in DetecorConstruction::ReadDetextorConfiguration Method + void ReadConfiguration(NPL::InputParser) ; + + // Construct detector and inialise sensitive part. + // Called After DetecorConstruction::AddDetector Method + void ConstructDetector(G4LogicalVolume* world) ; + + // Add Detector branch to the EventTree. + // Called After DetecorConstruction::AddDetector Method + void InitializeRootOutput() ; + + // Read sensitive part and fill the Root tree. + // Called at in the EventAction::EndOfEventAvtion + void ReadSensitive(const G4Event* event) ; + + public: // Scorer + // Initialize all Scorer used by the MUST2Array + void InitializeScorers() ; + + // Associated Scorer + G4MultiFunctionalDetector* m_GeLiScorer ; + //////////////////////////////////////////////////// + ///////////Event class to store Data//////////////// + //////////////////////////////////////////////////// + private: + TGeLiData* m_Event ; + + //////////////////////////////////////////////////// + ///////////////Private intern Data////////////////// + //////////////////////////////////////////////////// + private: // Geometry + // Detector Coordinate + vector<double> m_R; + vector<double> m_Theta; + vector<double> m_Phi; + + // Shape type + vector<string> m_Shape ; + + // Visualisation Attribute + G4VisAttributes* m_VisSquare; + G4VisAttributes* m_VisCylinder; + + // Needed for dynamic loading of the library + public: + static NPS::VDetector* Construct(); +}; +#endif diff --git a/NPSimulation/Detectors/quadranMSQ25/CMakeLists.txt b/NPSimulation/Detectors/quadranMSQ25/CMakeLists.txt new file mode 100644 index 000000000..724810f16 --- /dev/null +++ b/NPSimulation/Detectors/quadranMSQ25/CMakeLists.txt @@ -0,0 +1,2 @@ +add_library(NPSquadranMSQ25 SHARED quadranMSQ25.cc) +target_link_libraries(NPSquadranMSQ25 NPSCore ${ROOT_LIBRARIES} ${Geant4_LIBRARIES} ${NPLib_LIBRARIES} -lNPquadranMSQ25) diff --git a/NPSimulation/Detectors/quadranMSQ25/quadranMSQ25.cc b/NPSimulation/Detectors/quadranMSQ25/quadranMSQ25.cc new file mode 100644 index 000000000..64597a7a8 --- /dev/null +++ b/NPSimulation/Detectors/quadranMSQ25/quadranMSQ25.cc @@ -0,0 +1,399 @@ +/***************************************************************************** + * Copyright (C) 2009-2016 this file is part of the NPTool Project * + * * + * For the licensing terms see $NPTOOL/Licence/NPTool_Licence * + * For the list of contributors see $NPTOOL/Licence/Contributors * + *****************************************************************************/ + +/***************************************************************************** + * Original Author: Adrien MATTA contact address: matta@lpccaen.in2p3.fr * + * * + * Creation Date : January 2009 * + * Last update : October 2009 * + *---------------------------------------------------------------------------* + * Decription: * + * This class describe a 20um Silicium detector * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + *****************************************************************************/ + +// C++ headers +#include <cmath> +#include <limits> +#include <sstream> +// G4 Geometry object +#include "G4Box.hh" +#include "G4Trap.hh" +#include "G4Trd.hh" + +// G4 sensitive +#include "G4MultiFunctionalDetector.hh" +#include "G4SDManager.hh" + +// G4 various object +#include "G4Colour.hh" +#include "G4Material.hh" +#include "G4PVDivision.hh" +#include "G4PVPlacement.hh" +#include "G4SubtractionSolid.hh" +#include "G4Transform3D.hh" +#include "G4VisAttributes.hh" + +// NPTool header +#include "MaterialManager.hh" +#include "NPOptionManager.h" +#include "NPSDetectorFactory.hh" +#include "RootOutput.h" +#include "quadranMSQ25.hh" +#include "SiliconScorers.hh" +using namespace quadranMSQ25_LOCAL; + +// CLHEP header +#include "CLHEP/Random/RandGauss.h" + +using namespace std; +using namespace CLHEP; + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +// quadranMSQ25 Specific Method +quadranMSQ25::quadranMSQ25() { + InitializeMaterial(); + m_Event = new TquadranMSQ25Data(); + m_StripScorer = 0; +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +quadranMSQ25::~quadranMSQ25() {} +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +void quadranMSQ25::AddTelescope(G4ThreeVector TL, G4ThreeVector BL, G4ThreeVector BR, G4ThreeVector TR) { + m_DefinitionType.push_back(true); + + m_TL.push_back(TL); + m_BL.push_back(BL); + m_BR.push_back(BR); + m_TR.push_back(TR); + + m_R.push_back(0); + m_Theta.push_back(0); + m_Phi.push_back(0); + m_beta_u.push_back(0); + m_beta_v.push_back(0); + m_beta_w.push_back(0); +} +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +void quadranMSQ25::AddTelescope(G4double R, G4double Theta, G4double Phi, G4double beta_u, G4double beta_v, G4double beta_w) { + G4ThreeVector empty = G4ThreeVector(0, 0, 0); + + m_DefinitionType.push_back(false); + + m_R.push_back(R); + m_Theta.push_back(Theta); + m_Phi.push_back(Phi); + m_beta_u.push_back(beta_u); + m_beta_v.push_back(beta_v); + m_beta_w.push_back(beta_w); + + m_TL.push_back(empty); + m_BL.push_back(empty); + m_BR.push_back(empty); + m_TR.push_back(empty); +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +void quadranMSQ25::VolumeMaker(G4int DetNumber, G4ThreeVector Det_pos, G4RotationMatrix* Det_rot, G4LogicalVolume* world) { + G4double NbrTelescopes = DetNumber; + G4String DetectorNumber; + std::ostringstream Number; + Number << NbrTelescopes; + DetectorNumber = Number.str(); + + //////////////////////////////////////////////////////////////// + /////////General Geometry Parameter Definition ///////////////// + //////////////////////////////////////////////////////////////// + /////// Starting Volume Definition /////// + G4String Name = "quadranMSQ25" + DetectorNumber; + + G4Box* solidquadranMSQ25 = new G4Box(Name + "Solid", 0.5 * DetectorSize, 0.5 * DetectorSize, 0.5 * FrameThickness); + + G4LogicalVolume* logicquadranMSQ25 = new G4LogicalVolume(solidquadranMSQ25, m_MaterialVacuum, Name + "_logic", 0, 0); + + new G4PVPlacement(G4Transform3D(*Det_rot, Det_pos), logicquadranMSQ25, Name, world, false, DetNumber); + + logicquadranMSQ25->SetVisAttributes(G4VisAttributes::GetInvisible()); + // Frame is made of 4 thick box (2 Horizontal and 2 Vertical) + G4Box* solidFrameHorizontal = + new G4Box(Name + "_Frame", 0.5 * SiliconSize, 0.5 * (DetectorSize - SiliconSize) / 2, 0.5 * FrameThickness * mm); + G4Box* solidFrameVertical = + new G4Box(Name + "_Frame", 0.5 * (DetectorSize - SiliconSize) / 2, 0.5 * DetectorSize, 0.5 * FrameThickness * mm); + + G4LogicalVolume* logicFrameHorizontal = new G4LogicalVolume(solidFrameHorizontal, m_MaterialAl, Name, 0, 0); + G4VisAttributes* VisAtt1 = new G4VisAttributes(G4Colour(0.2, 0.5, 0.2)); + logicFrameHorizontal->SetVisAttributes(VisAtt1); + + G4LogicalVolume* logicFrameVertical = new G4LogicalVolume(solidFrameVertical, m_MaterialAl, Name, 0, 0); + logicFrameVertical->SetVisAttributes(VisAtt1); + + G4ThreeVector FrameTopPosition = G4ThreeVector(0, 0.5 * SiliconSize + 0.5 * (DetectorSize - SiliconSize) / 2, 0); + G4ThreeVector FrameBottomPosition = G4ThreeVector(0, -0.5 * SiliconSize - 0.5 * (DetectorSize - SiliconSize) / 2, 0); + G4ThreeVector FrameLeftPosition = G4ThreeVector(0.5 * SiliconSize + 0.5 * (DetectorSize - SiliconSize) / 2, 0, 0); + G4ThreeVector FrameRightPosition = G4ThreeVector(-0.5 * SiliconSize - 0.5 * (DetectorSize - SiliconSize) / 2, 0, 0); + + new G4PVPlacement(0, FrameTopPosition, logicFrameHorizontal, Name + "_Frame", logicquadranMSQ25, false, DetNumber); + + new G4PVPlacement(0, FrameBottomPosition, logicFrameHorizontal, Name + "_Frame", logicquadranMSQ25, false, DetNumber); + + new G4PVPlacement(0, FrameLeftPosition, logicFrameVertical, Name + "_Frame", logicquadranMSQ25, false, DetNumber); + + new G4PVPlacement(0, FrameRightPosition, logicFrameVertical, Name + "_Frame", logicquadranMSQ25, false, DetNumber); + + G4ThreeVector posAluFront = G4ThreeVector(0, 0, AluStripFront_PosZ); + G4ThreeVector posSi = G4ThreeVector(0, 0, 0); + G4ThreeVector posAluBack = G4ThreeVector(0, 0, AluStripBack_PosZ); + + G4Box* solidAlu = new G4Box("quadranMSQ25Alu", 0.5 * SiliconSize, 0.5 * SiliconSize, 0.5 * AluThickness); + + G4LogicalVolume* logicAlu = new G4LogicalVolume(solidAlu, m_MaterialAl, "logicAlu", 0, 0, 0); + + new G4PVPlacement(0, posAluFront, logicAlu, Name + "_AluFront", logicquadranMSQ25, true, DetNumber); + + new G4PVPlacement(0, posAluBack, logicAlu, Name + "_AluBack", logicquadranMSQ25, true, DetNumber); + + G4Box* solidSi = new G4Box("quadranMSQ25", 0.5 * SiliconSize, 0.5 * SiliconSize, 0.5 * SiliconThickness); + + G4LogicalVolume* logicSi = new G4LogicalVolume(solidSi, m_MaterialSilicon, "logicSi", 0, 0, 0); + + logicAlu->SetVisAttributes(G4VisAttributes::GetInvisible()); + + new G4PVPlacement(0, posSi, logicSi, Name + "_Si", logicquadranMSQ25, true, DetNumber); + + // attach it to the Silicon plate + logicSi->SetSensitiveDetector(m_StripScorer); +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +// Virtual Method of NPS::VDetector class + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +// Read stream at Configfile to pick-up parameters of detector (Position,...) +// Called in DetecorConstruction::ReadDetextorConfiguration Method +void quadranMSQ25::ReadConfiguration(NPL::InputParser parser) { + vector<NPL::InputBlock*> blocks = parser.GetAllBlocksWithToken("quadranMSQ25"); + if (NPOptionManager::getInstance()->GetVerboseLevel()) + cout << "//// " << blocks.size() << " detectors found " << endl; + + vector<string> cart = {"A", "B", "C", "D"}; + vector<string> sphe = {"R", "THETA", "PHI", "BETA"}; + + for (unsigned int i = 0; i < blocks.size(); i++) { + if (blocks[i]->HasTokenList(cart)) { + if (NPOptionManager::getInstance()->GetVerboseLevel()) + cout << endl << "//// quadranMSQ25 " << i + 1 << endl; + G4ThreeVector A = NPS::ConvertVector(blocks[i]->GetTVector3("A", "mm")); + G4ThreeVector B = NPS::ConvertVector(blocks[i]->GetTVector3("B", "mm")); + G4ThreeVector C = NPS::ConvertVector(blocks[i]->GetTVector3("C", "mm")); + G4ThreeVector D = NPS::ConvertVector(blocks[i]->GetTVector3("D", "mm")); + AddTelescope(A, B, C, D); + } + else if (blocks[i]->HasTokenList(sphe)) { + if (NPOptionManager::getInstance()->GetVerboseLevel()) + cout << endl << "//// quadranMSQ25 " << i + 1 << endl; + double R = blocks[i]->GetDouble("R", "mm"); + double Theta = blocks[i]->GetDouble("THETA", "deg"); + double Phi = blocks[i]->GetDouble("PHI", "deg"); + vector<double> beta = blocks[i]->GetVectorDouble("BETA", "deg"); + AddTelescope(R, Theta, Phi, beta[0], beta[1], beta[2]); + } + else { + cout << "ERROR: check your input file formatting " << endl; + exit(1); + } + } +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +// Construct detector and inialise sensitive part. +// Called After DetecorConstruction::AddDetector Method +void quadranMSQ25::ConstructDetector(G4LogicalVolume* world) { + + G4RotationMatrix* Det_rot = NULL; + G4ThreeVector Det_pos = G4ThreeVector(0, 0, 0); + G4ThreeVector Det_u = G4ThreeVector(0, 0, 0); + G4ThreeVector Det_v = G4ThreeVector(0, 0, 0); + G4ThreeVector Det_w = G4ThreeVector(0, 0, 0); + + G4int NumberOfDetector = m_DefinitionType.size(); + + for (G4int i = 0; i < NumberOfDetector; i++) { + // By Point + if (m_DefinitionType[i]) { + // (u,v,w) unitary vector associated to telescope referencial + // (u,v) // to silicon plan + // w perpendicular to (u,v) plan and pointing outside + Det_u = m_TL[i] - m_BL[i]; + Det_u = Det_u.unit(); + Det_v = m_BR[i] - m_BL[i]; + Det_v = Det_v.unit(); + Det_w = Det_u.cross(Det_v); + Det_w = Det_w.unit(); + // Passage Matrix from Lab Referential to Telescope Referential + // MUST2 + Det_rot = new G4RotationMatrix(Det_u, Det_v, Det_w); + // translation to place Telescope + Det_pos = (m_TR[i] + m_TL[i] + m_BL[i] + m_BR[i]) / 4; + } + + // By Angle + else { + G4double Theta = m_Theta[i]; + G4double Phi = m_Phi[i]; + // This part because if Phi and Theta = 0 equation are false + if (Theta == 0) + Theta = 0.0001; + if (Theta == 2 * cos(0)) + Theta = 2 * acos(0) - 0.00001; + if (Phi == 0) + Phi = 0.0001; + + // (u,v,w) unitary vector associated to telescope referencial + // (u,v) // to silicon plan + // w perpendicular to (u,v) plan and pointing ThirdStage + // Phi is angle between X axis and projection in (X,Y) plan + // Theta is angle between position vector and z axis + G4double wX = m_R[i] * sin(Theta / rad) * cos(Phi / rad); + G4double wY = m_R[i] * sin(Theta / rad) * sin(Phi / rad); + G4double wZ = m_R[i] * cos(Theta / rad); + Det_w = G4ThreeVector(wX, wY, wZ); + + // vector corresponding to the center of the module + G4ThreeVector CT = Det_w; + + // vector parallel to one axis of silicon plane + G4double ii = cos(Theta / rad) * cos(Phi / rad); + G4double jj = cos(Theta / rad) * sin(Phi / rad); + G4double kk = -sin(Theta / rad); + G4ThreeVector Y = G4ThreeVector(ii, jj, kk); + + Det_w = Det_w.unit(); + Det_u = Det_w.cross(Y); + Det_v = Det_w.cross(Det_u); + Det_v = Det_v.unit(); + Det_u = Det_u.unit(); + + // Passage Matrix from Lab Referential to Telescope Referential + // MUST2 + Det_rot = new G4RotationMatrix(Det_u, Det_v, Det_w); + // Telescope is rotate of Beta angle around Det_v axis. + Det_rot->rotate(m_beta_u[i], Det_u); + Det_rot->rotate(m_beta_v[i], Det_v); + Det_rot->rotate(m_beta_w[i], Det_w); + // translation to place Telescope + Det_pos = Det_w + CT; + } + + VolumeMaker(i + 1, Det_pos, Det_rot, world); + } + + delete Det_rot; +} +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +// Add Detector branch to the EventTree. +// Called After DetecorConstruction::AddDetector Method +void quadranMSQ25::InitializeRootOutput() { + RootOutput* pAnalysis = RootOutput::getInstance(); + TTree* pTree = pAnalysis->GetTree(); + if (!pTree->FindBranch("quadranMSQ25")) { + pTree->Branch("quadranMSQ25", "TquadranMSQ25Data", &m_Event); + } + pTree->SetBranchAddress("quadranMSQ25", &m_Event); +} +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +// Read sensitive part and fill the Root tree. +// Called at in the EventAction::EndOfEventAvtion +void quadranMSQ25::ReadSensitive(const G4Event* event) { + m_Event->Clear(); + + /////////// + NPS::HitsMap<G4double*>* StripHitMap; + std::map<G4int, G4double**>::iterator Strip_itr; + + G4int StripCollectionID = G4SDManager::GetSDMpointer()->GetCollectionID("quadranMSQ25_Scorer/StripScorer"); + StripHitMap = (NPS::HitsMap<G4double*>*)(event->GetHCofThisEvent()->GetHC(StripCollectionID)); + + // Loop on the Strip map + for (Strip_itr = StripHitMap->GetMap()->begin(); Strip_itr != StripHitMap->GetMap()->end(); Strip_itr++) { + + G4double* Info = *(Strip_itr->second); + + double Energy = Info[0]; + + if (Energy > EnergyThreshold) { + double Time = Info[1]; + int DetNbr = (int)Info[7]; + int StripFront = (int)Info[8]; + + m_Event->SetEnergyDetectorNbr(DetNbr); + m_Event->SetEnergyStripNbr(StripFront); + m_Event->SetEnergy(RandGauss::shoot(Energy, ResoEnergy)); + + m_Event->SetTimeDetectorNbr(DetNbr); + m_Event->SetTimeStripNbr(StripFront); + m_Event->SetTime(RandGauss::shoot(Time, ResoTime)); + } + } + // clear map for next event + StripHitMap->clear(); +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +void quadranMSQ25::InitializeScorers() { + bool already_exist = false; + // Silicon Associate Scorer + m_StripScorer = CheckScorer("quadranMSQ25_Scorer", already_exist); + if (already_exist) + return; + + G4VPrimitiveScorer* StripScorer = + new SILICONSCORERS::PS_Silicon_Rectangle("StripScorer", 0, DetectorSize, DetectorSize, NumberOfStripH, NumberOfStripL); + + m_StripScorer->RegisterPrimitive(StripScorer); + G4SDManager::GetSDMpointer()->AddNewDetector(m_StripScorer); +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//////////////////////////////////////////////////////////////// +/////////////////Material Definition /////////////////////////// +//////////////////////////////////////////////////////////////// +void quadranMSQ25::InitializeMaterial() { + m_MaterialSilicon = MaterialManager::getInstance()->GetMaterialFromLibrary("Si"); + m_MaterialAl = MaterialManager::getInstance()->GetMaterialFromLibrary("Al"); + m_MaterialVacuum = MaterialManager::getInstance()->GetMaterialFromLibrary("Vacuum"); +} +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... + +//////////////////////////////////////////////////////////////////////////////// +// Construct Method to be pass to the DetectorFactory // +//////////////////////////////////////////////////////////////////////////////// +NPS::VDetector* quadranMSQ25::Construct() { return (NPS::VDetector*)new quadranMSQ25(); } + +//////////////////////////////////////////////////////////////////////////////// +// Registering the construct method to the factory // +//////////////////////////////////////////////////////////////////////////////// +extern "C" { +class proxy_nps_quadranmsq25 { + public: + proxy_nps_quadranmsq25() { + NPS::DetectorFactory::getInstance()->AddToken("quadranMSQ25", "quadranMSQ25"); + NPS::DetectorFactory::getInstance()->AddDetector("quadranMSQ25", quadranMSQ25::Construct); + } +}; + +proxy_nps_quadranmsq25 p_nps_quadranmsq25; +} diff --git a/NPSimulation/Detectors/quadranMSQ25/quadranMSQ25.hh b/NPSimulation/Detectors/quadranMSQ25/quadranMSQ25.hh new file mode 100644 index 000000000..2de0b4f7a --- /dev/null +++ b/NPSimulation/Detectors/quadranMSQ25/quadranMSQ25.hh @@ -0,0 +1,170 @@ +#ifndef quadranMSQ25_h +#define quadranMSQ25_h 1 +/***************************************************************************** + * Copyright (C) 2009-2016 this file is part of the NPTool Project * + * * + * For the licensing terms see $NPTOOL/Licence/NPTool_Licence * + * For the list of contributors see $NPTOOL/Licence/Contributors * + *****************************************************************************/ + +/***************************************************************************** + * Original Author: Adrien MATTA contact address: matta@lpccaen.in2p3.fr * + * * + * Creation Date : January 2009 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class describe a 20um Silicium detector * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + *****************************************************************************/ +// C++ header +#include <string> +#include <vector> + +// G4 header defining G4 types +#include "globals.hh" + +// G4 headers +#include "G4ThreeVector.hh" +#include "G4RotationMatrix.hh" +#include "G4LogicalVolume.hh" + +// NPSimulation header +#include "NPSVDetector.hh" + +// NPLib +#include "TquadranMSQ25Data.h" +#include "NPInputParser.h" +using namespace std; +using namespace CLHEP; + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +namespace quadranMSQ25_LOCAL{ + // Energy and time Resolution + const G4double ResoTime = 0 ; //unchecked + const G4double ResoEnergy = 0.043 ; //unchecked// = 150keV of Resolution // Unit is MeV/2.35 + const G4double EnergyThreshold = 100*keV; //unchecked + // Geometry + const G4double DetectorSize = 70*mm ; + const G4double SiliconThickness = 500*micrometer ; + const G4double FrameThickness = 3.2*mm ; + const G4double SiliconSize = 50*mm ; //unchecked + const G4double AluThickness = 0.3*micrometer ; + const G4int NumberOfStripH = 2 ; + const G4int NumberOfStripL = 2 ; + + const G4double AluStripFront_PosZ = -0.5*SiliconThickness - 0.5*AluThickness ; //unchecked + const G4double Si_PosZ = 0 ; //unchecked + const G4double AluStripBack_PosZ = 0.5*SiliconThickness + 0.5*AluThickness ; //unchecked +} + +class quadranMSQ25 : public NPS::VDetector{ + //////////////////////////////////////////////////// + /////// Default Constructor and Destructor ///////// + //////////////////////////////////////////////////// +public: + quadranMSQ25() ; + ~quadranMSQ25() ; + + //////////////////////////////////////////////////// + //////// Specific Function of this Class /////////// + //////////////////////////////////////////////////// +public: + // By Position Method + void AddTelescope( G4ThreeVector TL , + G4ThreeVector BL , + G4ThreeVector BR , + G4ThreeVector TR ); + // By Angle Method + void AddTelescope( G4double R , + G4double Theta , + G4double Phi , + G4double beta_u , + G4double beta_v , + G4double beta_w ); + + // Effectively construct Volume + // Avoid to have two time same code for Angle and Point definition + void VolumeMaker( G4int DetectorNumber , + G4ThreeVector MMpos , + G4RotationMatrix* MMrot , + G4LogicalVolume* world ); + + + //////////////////////////////////////////////////// + ///////// Inherite from NPS::VDetector class /////////// + //////////////////////////////////////////////////// +public: + // Read stream at Configfile to pick-up parameters of detector (Position,...) + // Called in DetecorConstruction::ReadDetextorConfiguration Method + void ReadConfiguration(NPL::InputParser) ; + + // Construct detector and inialise sensitive part. + // Called After DetecorConstruction::AddDetector Method + void ConstructDetector(G4LogicalVolume* world) ; + + // Add Detector branch to the EventTree. + // Called After DetecorConstruction::AddDetector Method + void InitializeRootOutput() ; + + // Read sensitive part and fill the Root tree. + // Called at in the EventAction::EndOfEventAvtion + void ReadSensitive(const G4Event* event) ; + + + //////////////////////////////////////////////////// + ///////////Event class to store Data//////////////// + //////////////////////////////////////////////////// +private: + TquadranMSQ25Data* m_Event ; + + //////////////////////////////////////////////////// + ///////////////// Scorer Related /////////////////// + //////////////////////////////////////////////////// + +private: + // Initialize all Scorer used by the MUST2Array + void InitializeScorers() ; + + // Scorer Associate to the 20um Silicon stage + G4MultiFunctionalDetector* m_StripScorer ; + + + +private: + // Initialize mmaterial used in detector definition + void InitializeMaterial(); + + // List of material + G4Material* m_MaterialSilicon ; + G4Material* m_MaterialAl ; + G4Material* m_MaterialVacuum ; + + //////////////////////////////////////////////////// + ///////////////Private intern Data////////////////// + //////////////////////////////////////////////////// +private: + // True if Define by Position, False is Define by angle + vector<bool> m_DefinitionType ; + + // Used for "By Point Definition" + vector<G4ThreeVector> m_TL ; // Top Left Corner Position Vector + vector<G4ThreeVector> m_BL ; // Bottom Left Corner Position Vector + vector<G4ThreeVector> m_BR ; // Bottom Right Corner Position Vector + vector<G4ThreeVector> m_TR ; // Center Corner Position Vector + + // Used for "By Angle Definition" + vector<G4double> m_R ; // | + vector<G4double> m_Theta ; // > Spherical coordinate of Strips Silicium Plate + vector<G4double> m_Phi ; // | + + vector<G4double> m_beta_u ; // | + vector<G4double> m_beta_v ; // >Tilt angle of the Telescope + vector<G4double> m_beta_w ; // | +public: + static NPS::VDetector* Construct(); +}; +#endif diff --git a/NPSimulation/EventGenerator/EventGeneratorIsotropic.cc b/NPSimulation/EventGenerator/EventGeneratorIsotropic.cc index 40a540f87..de169a993 100644 --- a/NPSimulation/EventGenerator/EventGeneratorIsotropic.cc +++ b/NPSimulation/EventGenerator/EventGeneratorIsotropic.cc @@ -106,6 +106,7 @@ void EventGeneratorIsotropic::ReadConfiguration(NPL::InputParser parser){ else if(particleName[j]=="mu-") { it->m_particleName.push_back("mu-") ;} else if(particleName[j]=="neutron") {it->m_particleName.push_back("neutron") ;} else if(particleName[j]=="electron" || particleName[j]=="e-") {it->m_particleName.push_back("e-");} + else if(particleName[j]=="positron" || particleName[j]=="e+") {it->m_particleName.push_back("e+");} else it->m_particleName.push_back(particleName[j]); } @@ -151,7 +152,7 @@ void EventGeneratorIsotropic::GenerateEvent(G4Event*){ par.m_particle=NULL; if(par.m_particle==NULL){ - if(par.m_particleName[p]=="gamma" || par.m_particleName[p]=="neutron" || par.m_particleName[p]=="opticalphoton" || par.m_particleName[p]=="mu+" || par.m_particleName[p]=="mu-" || par.m_particleName[p]=="e-"){ + if(par.m_particleName[p]=="gamma" || par.m_particleName[p]=="neutron" || par.m_particleName[p]=="opticalphoton" || par.m_particleName[p]=="mu+" || par.m_particleName[p]=="mu-" || par.m_particleName[p]=="e-" || par.m_particleName[p]=="e+"){ par.m_particle = G4ParticleTable::GetParticleTable()->FindParticle(par.m_particleName[p].c_str()); } else{ -- GitLab