Skip to content
Snippets Groups Projects
Commit f45eb379 authored by Xythere's avatar Xythere
Browse files

Added Plastic_BEDO and Coaxial_Germanium detectors relevant for experiments @ ALTO

parent 545ede27
No related branches found
No related tags found
1 merge request!27Draft: [Epic] Preparation of the environement for the new GaseousDetectorScorers...
Showing
with 2675 additions and 0 deletions
add_custom_command(OUTPUT TCoaxial_GermaniumPhysicsDict.cxx COMMAND ../../scripts/build_dict.sh TCoaxial_GermaniumPhysics.h TCoaxial_GermaniumPhysicsDict.cxx TCoaxial_GermaniumPhysics.rootmap libNPCoaxial_Germanium.dylib DEPENDS TCoaxial_GermaniumPhysics.h)
add_custom_command(OUTPUT TCoaxial_GermaniumDataDict.cxx COMMAND ../../scripts/build_dict.sh TCoaxial_GermaniumData.h TCoaxial_GermaniumDataDict.cxx TCoaxial_GermaniumData.rootmap libNPCoaxial_Germanium.dylib DEPENDS TCoaxial_GermaniumData.h)
add_library(NPCoaxial_Germanium SHARED TCoaxial_GermaniumSpectra.cxx TCoaxial_GermaniumData.cxx TCoaxial_GermaniumPhysics.cxx TCoaxial_GermaniumDataDict.cxx TCoaxial_GermaniumPhysicsDict.cxx )
target_link_libraries(NPCoaxial_Germanium ${ROOT_LIBRARIES} NPCore)
install(FILES TCoaxial_GermaniumData.h TCoaxial_GermaniumPhysics.h TCoaxial_GermaniumSpectra.h DESTINATION ${CMAKE_INCLUDE_OUTPUT_DIRECTORY})
/*****************************************************************************
* Copyright (C) 2009-2025 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: Léo Plagnol contact address: leo.plagnol@ijclab.in2p3.fr *
* *
* Creation Date : January 2025 *
* Last update : *
*---------------------------------------------------------------------------*
* Decription: *
* This class hold Coaxial_Germanium Raw data *
* *
*---------------------------------------------------------------------------*
* Comment: *
* *
* *
*****************************************************************************/
#include "TCoaxial_GermaniumData.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
using namespace std;
ClassImp(TCoaxial_GermaniumData)
//////////////////////////////////////////////////////////////////////
TCoaxial_GermaniumData::TCoaxial_GermaniumData() {
}
//////////////////////////////////////////////////////////////////////
TCoaxial_GermaniumData::~TCoaxial_GermaniumData() {
}
//////////////////////////////////////////////////////////////////////
void TCoaxial_GermaniumData::Clear() {
// Energy
fCoaxial_Germanium_E_DetectorNbr.clear();
fCoaxial_Germanium_Energy.clear();
// Time
fCoaxial_Germanium_T_DetectorNbr.clear();
fCoaxial_Germanium_Time.clear();
}
//////////////////////////////////////////////////////////////////////
void TCoaxial_GermaniumData::Dump() const {
// This method is very useful for debuging and worth the dev.
cout << "XXXXXXXXXXXXXXXXXXXXXXXX New Event [TCoaxial_GermaniumData::Dump()] XXXXXXXXXXXXXXXXX" << endl;
// Energy
size_t mysize = fCoaxial_Germanium_E_DetectorNbr.size();
cout << "Coaxial_Germanium_E_Mult: " << mysize << endl;
for (size_t i = 0 ; i < mysize ; i++){
cout << "DetNbr: " << fCoaxial_Germanium_E_DetectorNbr[i]
<< " Energy: " << fCoaxial_Germanium_Energy[i];
}
// Time
mysize = fCoaxial_Germanium_T_DetectorNbr.size();
cout << "Coaxial_Germanium_T_Mult: " << mysize << endl;
for (size_t i = 0 ; i < mysize ; i++){
cout << "DetNbr: " << fCoaxial_Germanium_T_DetectorNbr[i]
<< " Time: " << fCoaxial_Germanium_Time[i];
}
}
#ifndef __Coaxial_GermaniumDATA__
#define __Coaxial_GermaniumDATA__
/*****************************************************************************
* Copyright (C) 2009-2025 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: Léo Plagnol contact address: leo.plagnol@ijclab.in2p3.fr *
* *
* Creation Date : January 2025 *
* Last update : *
*---------------------------------------------------------------------------*
* Decription: *
* This class hold Coaxial_Germanium Raw data *
* *
*---------------------------------------------------------------------------*
* Comment: *
* *
* *
*****************************************************************************/
// STL
#include <vector>
using namespace std;
// ROOT
#include "TObject.h"
class TCoaxial_GermaniumData : public TObject {
//////////////////////////////////////////////////////////////
// data members are hold into vectors in order
// to allow multiplicity treatment
private:
// Energy
vector<UShort_t> fCoaxial_Germanium_E_DetectorNbr;
vector<Double_t> fCoaxial_Germanium_Energy;
// Time
vector<UShort_t> fCoaxial_Germanium_T_DetectorNbr;
vector<Double_t> fCoaxial_Germanium_Time;
//////////////////////////////////////////////////////////////
// Constructor and destructor
public:
TCoaxial_GermaniumData();
~TCoaxial_GermaniumData();
//////////////////////////////////////////////////////////////
// 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){
fCoaxial_Germanium_E_DetectorNbr.push_back(DetNbr);
fCoaxial_Germanium_Energy.push_back(Energy);
};//!
// Time
inline void SetTime(const UShort_t& DetNbr,const Double_t& Time) {
fCoaxial_Germanium_T_DetectorNbr.push_back(DetNbr);
fCoaxial_Germanium_Time.push_back(Time);
};//!
////////////////////// GETTERS ////////////////////////
// Energy
inline UShort_t GetMultEnergy() const
{return fCoaxial_Germanium_E_DetectorNbr.size();}
inline UShort_t GetE_DetectorNbr(const unsigned int &i) const
{return fCoaxial_Germanium_E_DetectorNbr[i];}//!
inline Double_t Get_Energy(const unsigned int &i) const
{return fCoaxial_Germanium_Energy[i];}//!
// Time
inline UShort_t GetMultTime() const
{return fCoaxial_Germanium_T_DetectorNbr.size();}
inline UShort_t GetT_DetectorNbr(const unsigned int &i) const
{return fCoaxial_Germanium_T_DetectorNbr[i];}//!
inline Double_t Get_Time(const unsigned int &i) const
{return fCoaxial_Germanium_Time[i];}//!
//////////////////////////////////////////////////////////////
// Required for ROOT dictionnary
ClassDef(TCoaxial_GermaniumData,1) // Coaxial_GermaniumData structure
};
#endif
/*****************************************************************************
* Copyright (C) 2009-2025 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: Léo Plagnol contact address: leo.plagnol@ijclab.in2p3.fr *
* *
* Creation Date : January 2025 *
* Last update : *
*---------------------------------------------------------------------------*
* Decription: *
* This class hold Coaxial_Germanium Treated data *
* *
*---------------------------------------------------------------------------*
* Comment: *
* *
* *
*****************************************************************************/
#include "TCoaxial_GermaniumPhysics.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(TCoaxial_GermaniumPhysics)
///////////////////////////////////////////////////////////////////////////
TCoaxial_GermaniumPhysics::TCoaxial_GermaniumPhysics()
: m_EventData(new TCoaxial_GermaniumData),
m_PreTreatedData(new TCoaxial_GermaniumData),
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 TCoaxial_GermaniumPhysics::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 TCoaxial_GermaniumPhysics::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 TCoaxial_GermaniumPhysics::BuildSimplePhysicalEvent() {
BuildPhysicalEvent();
}
///////////////////////////////////////////////////////////////////////////
void TCoaxial_GermaniumPhysics::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 TCoaxial_GermaniumPhysics::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("Coaxial_Germanium/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("Coaxial_Germanium/TIME"+NPL::itoa(m_EventData->GetT_DetectorNbr(i)),m_EventData->Get_Time(i));
m_PreTreatedData->SetTime(m_EventData->GetT_DetectorNbr(i), Time);
}
}
///////////////////////////////////////////////////////////////////////////
void TCoaxial_GermaniumPhysics::ReadAnalysisConfig() {
bool ReadingStatus = false;
// path to file
string FileName = "./configs/ConfigCoaxial_Germanium.dat";
// open analysis config file
ifstream AnalysisConfigFile;
AnalysisConfigFile.open(FileName.c_str());
if (!AnalysisConfigFile.is_open()) {
cout << " No ConfigCoaxial_Germanium.dat found: Default parameter loaded for Analayis " << FileName << endl;
return;
}
cout << " Loading user parameter for Analysis from ConfigCoaxial_Germanium.dat " << endl;
// Save it in a TAsciiFile
TAsciiFile* asciiConfig = RootOutput::getInstance()->GetAsciiFileAnalysisConfig();
asciiConfig->AppendLine("%%% ConfigCoaxial_Germanium.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 = "ConfigCoaxial_Germanium";
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 TCoaxial_GermaniumPhysics::Clear() {
DetectorNumber.clear();
Energy.clear();
Time.clear();
}
///////////////////////////////////////////////////////////////////////////
void TCoaxial_GermaniumPhysics::ReadConfiguration(NPL::InputParser parser) {
vector<NPL::InputBlock*> blocks = parser.GetAllBlocksWithToken("Coaxial_Germanium");
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 << "//// Coaxial_Germanium " << 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 << "//// Coaxial_Germanium " << 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 TCoaxial_GermaniumPhysics::InitSpectra() {
m_Spectra = new TCoaxial_GermaniumSpectra(m_NumberOfDetectors);
}
///////////////////////////////////////////////////////////////////////////
void TCoaxial_GermaniumPhysics::FillSpectra() {
m_Spectra -> FillRawSpectra(m_EventData);
m_Spectra -> FillPreTreatedSpectra(m_PreTreatedData);
m_Spectra -> FillPhysicsSpectra(m_EventPhysics);
}
///////////////////////////////////////////////////////////////////////////
void TCoaxial_GermaniumPhysics::CheckSpectra() {
m_Spectra->CheckSpectra();
}
///////////////////////////////////////////////////////////////////////////
void TCoaxial_GermaniumPhysics::ClearSpectra() {
// To be done
}
///////////////////////////////////////////////////////////////////////////
map< string , TH1*> TCoaxial_GermaniumPhysics::GetSpectra() {
if(m_Spectra)
return m_Spectra->GetMapHisto();
else{
map< string , TH1*> empty;
return empty;
}
}
///////////////////////////////////////////////////////////////////////////
void TCoaxial_GermaniumPhysics::WriteSpectra() {
m_Spectra->WriteSpectra();
}
///////////////////////////////////////////////////////////////////////////
void TCoaxial_GermaniumPhysics::AddParameterToCalibrationManager() {
CalibrationManager* Cal = CalibrationManager::getInstance();
for (int i = 0; i < m_NumberOfDetectors; ++i) {
Cal->AddParameter("Coaxial_Germanium", "D"+ NPL::itoa(i+1)+"_ENERGY","Coaxial_Germanium_D"+ NPL::itoa(i+1)+"_ENERGY");
Cal->AddParameter("Coaxial_Germanium", "D"+ NPL::itoa(i+1)+"_TIME","Coaxial_Germanium_D"+ NPL::itoa(i+1)+"_TIME");
}
}
///////////////////////////////////////////////////////////////////////////
void TCoaxial_GermaniumPhysics::InitializeRootInputRaw() {
TChain* inputChain = RootInput::getInstance()->GetChain();
inputChain->SetBranchStatus("Coaxial_Germanium", true );
inputChain->SetBranchAddress("Coaxial_Germanium", &m_EventData );
}
///////////////////////////////////////////////////////////////////////////
void TCoaxial_GermaniumPhysics::InitializeRootInputPhysics() {
TChain* inputChain = RootInput::getInstance()->GetChain();
inputChain->SetBranchAddress("Coaxial_Germanium", &m_EventPhysics);
}
///////////////////////////////////////////////////////////////////////////
void TCoaxial_GermaniumPhysics::InitializeRootOutput() {
TTree* outputTree = RootOutput::getInstance()->GetTree();
outputTree->Branch("Coaxial_Germanium", "TCoaxial_GermaniumPhysics", &m_EventPhysics);
}
////////////////////////////////////////////////////////////////////////////////
// Construct Method to be pass to the DetectorFactory //
////////////////////////////////////////////////////////////////////////////////
NPL::VDetector* TCoaxial_GermaniumPhysics::Construct() {
return (NPL::VDetector*) new TCoaxial_GermaniumPhysics();
}
////////////////////////////////////////////////////////////////////////////////
// Registering the construct method to the factory //
////////////////////////////////////////////////////////////////////////////////
extern "C"{
class proxy_Coaxial_Germanium{
public:
proxy_Coaxial_Germanium(){
NPL::DetectorFactory::getInstance()->AddToken("Coaxial_Germanium","Coaxial_Germanium");
NPL::DetectorFactory::getInstance()->AddDetector("Coaxial_Germanium",TCoaxial_GermaniumPhysics::Construct);
}
};
proxy_Coaxial_Germanium p_Coaxial_Germanium;
}
#ifndef TCoaxial_GermaniumPHYSICS_H
#define TCoaxial_GermaniumPHYSICS_H
/*****************************************************************************
* Copyright (C) 2009-2025 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: Léo Plagnol contact address: leo.plagnol@ijclab.in2p3.fr *
* *
* Creation Date : January 2025 *
* Last update : *
*---------------------------------------------------------------------------*
* Decription: *
* This class hold Coaxial_Germanium 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 "TCoaxial_GermaniumData.h"
#include "TCoaxial_GermaniumSpectra.h"
#include "NPCalibrationManager.h"
#include "NPVDetector.h"
#include "NPInputParser.h"
// forward declaration
class TCoaxial_GermaniumSpectra;
class TCoaxial_GermaniumPhysics : public TObject, public NPL::VDetector {
//////////////////////////////////////////////////////////////
// constructor and destructor
public:
TCoaxial_GermaniumPhysics();
~TCoaxial_GermaniumPhysics() {};
//////////////////////////////////////////////////////////////
// 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 TCoaxial_GermaniumSpectra class
// instantiate the TCoaxial_GermaniumSpectra 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 Coaxial_Germanium 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 TCoaxial_GermaniumData object to TCoaxial_GermaniumPhysics.
// needed for online analysis for example
void SetRawDataPointer(TCoaxial_GermaniumData* rawDataPointer) {m_EventData = rawDataPointer;}
// objects are not written in the TTree
private:
TCoaxial_GermaniumData* m_EventData; //!
TCoaxial_GermaniumData* m_PreTreatedData; //!
TCoaxial_GermaniumPhysics* m_EventPhysics; //!
// getters for raw and pre-treated data object
public:
TCoaxial_GermaniumData* GetRawData() const {return m_EventData;}
TCoaxial_GermaniumData* 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:
TCoaxial_GermaniumSpectra* m_Spectra; // !
// spectra getter
public:
map<string, TH1*> GetSpectra();
// Static constructor to be passed to the Detector Factory
public:
static NPL::VDetector* Construct();
ClassDef(TCoaxial_GermaniumPhysics,1) // Coaxial_GermaniumPhysics structure
};
#endif
/*****************************************************************************
* Copyright (C) 2009-2025 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: Léo Plagnol contact address: leo.plagnol@ijclab.in2p3.fr *
* *
* Creation Date : January 2025 *
* Last update : *
*---------------------------------------------------------------------------*
* Decription: *
* This class hold Coaxial_Germanium Spectra *
* *
*---------------------------------------------------------------------------*
* Comment: *
* *
* *
*****************************************************************************/
// class header
#include "TCoaxial_GermaniumSpectra.h"
// STL
#include <iostream>
#include <string>
using namespace std;
// NPTool header
#include "NPOptionManager.h"
////////////////////////////////////////////////////////////////////////////////
TCoaxial_GermaniumSpectra::TCoaxial_GermaniumSpectra()
: fNumberOfDetectors(0) {
SetName("Coaxial_Germanium");
}
////////////////////////////////////////////////////////////////////////////////
TCoaxial_GermaniumSpectra::TCoaxial_GermaniumSpectra(unsigned int NumberOfDetectors) {
if(NPOptionManager::getInstance()->GetVerboseLevel()>0)
cout << "************************************************" << endl
<< "TCoaxial_GermaniumSpectra : Initalizing control spectra for "
<< NumberOfDetectors << " Detectors" << endl
<< "************************************************" << endl ;
SetName("Coaxial_Germanium");
fNumberOfDetectors = NumberOfDetectors;
InitRawSpectra();
InitPreTreatedSpectra();
InitPhysicsSpectra();
}
////////////////////////////////////////////////////////////////////////////////
TCoaxial_GermaniumSpectra::~TCoaxial_GermaniumSpectra() {
}
////////////////////////////////////////////////////////////////////////////////
void TCoaxial_GermaniumSpectra::InitRawSpectra() {
static string name;
for (unsigned int i = 0; i < fNumberOfDetectors; i++) { // loop on number of detectors
// Energy
name = "Coaxial_Germanium"+NPL::itoa(i+1)+"_ENERGY_RAW";
AddHisto1D(name, name, 4096, 0, 16384, "Coaxial_Germanium/RAW");
// Time
name = "Coaxial_Germanium"+NPL::itoa(i+1)+"_TIME_RAW";
AddHisto1D(name, name, 4096, 0, 16384, "Coaxial_Germanium/RAW");
} // end loop on number of detectors
}
////////////////////////////////////////////////////////////////////////////////
void TCoaxial_GermaniumSpectra::InitPreTreatedSpectra() {
static string name;
for (unsigned int i = 0; i < fNumberOfDetectors; i++) { // loop on number of detectors
// Energy
name = "Coaxial_Germanium"+NPL::itoa(i+1)+"_ENERGY_CAL";
AddHisto1D(name, name, 500, 0, 25, "Coaxial_Germanium/CAL");
// Time
name = "Coaxial_Germanium"+NPL::itoa(i+1)+"_TIME_CAL";
AddHisto1D(name, name, 500, 0, 25, "Coaxial_Germanium/CAL");
} // end loop on number of detectors
}
////////////////////////////////////////////////////////////////////////////////
void TCoaxial_GermaniumSpectra::InitPhysicsSpectra() {
static string name;
// Kinematic Plot
name = "Coaxial_Germanium_ENERGY_TIME";
AddHisto2D(name, name, 500, 0, 500, 500, 0, 50, "Coaxial_Germanium/PHY");
}
////////////////////////////////////////////////////////////////////////////////
void TCoaxial_GermaniumSpectra::FillRawSpectra(TCoaxial_GermaniumData* RawData) {
static string name;
static string family;
// Energy
unsigned int sizeE = RawData->GetMultEnergy();
for (unsigned int i = 0; i < sizeE; i++) {
name = "Coaxial_Germanium"+NPL::itoa(RawData->GetE_DetectorNbr(i))+"_ENERGY_RAW";
family = "Coaxial_Germanium/RAW";
FillSpectra(family,name,RawData->Get_Energy(i));
}
// Time
unsigned int sizeT = RawData->GetMultTime();
for (unsigned int i = 0; i < sizeT; i++) {
name = "Coaxial_Germanium"+NPL::itoa(RawData->GetT_DetectorNbr(i))+"_TIME_RAW";
family = "Coaxial_Germanium/RAW";
FillSpectra(family,name,RawData->Get_Time(i));
}
}
////////////////////////////////////////////////////////////////////////////////
void TCoaxial_GermaniumSpectra::FillPreTreatedSpectra(TCoaxial_GermaniumData* PreTreatedData) {
static string name;
static string family;
// Energy
unsigned int sizeE = PreTreatedData->GetMultEnergy();
for (unsigned int i = 0; i < sizeE; i++) {
name = "Coaxial_Germanium"+NPL::itoa(PreTreatedData->GetE_DetectorNbr(i))+"_ENERGY_CAL";
family = "Coaxial_Germanium/CAL";
FillSpectra(family,name,PreTreatedData->Get_Energy(i));
}
// Time
unsigned int sizeT = PreTreatedData->GetMultTime();
for (unsigned int i = 0; i < sizeT; i++) {
name = "Coaxial_Germanium"+NPL::itoa(PreTreatedData->GetT_DetectorNbr(i))+"_TIME_CAL";
family = "Coaxial_Germanium/CAL";
FillSpectra(family,name,PreTreatedData->Get_Time(i));
}
}
////////////////////////////////////////////////////////////////////////////////
void TCoaxial_GermaniumSpectra::FillPhysicsSpectra(TCoaxial_GermaniumPhysics* Physics) {
static string name;
static string family;
family= "Coaxial_Germanium/PHY";
// Energy vs time
unsigned int sizeE = Physics->Energy.size();
for(unsigned int i = 0 ; i < sizeE ; i++){
name = "Coaxial_Germanium_ENERGY_TIME";
FillSpectra(family,name,Physics->Energy[i],Physics->Time[i]);
}
}
#ifndef TCoaxial_GermaniumSPECTRA_H
#define TCoaxial_GermaniumSPECTRA_H
/*****************************************************************************
* Copyright (C) 2009-2025 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: Léo Plagnol contact address: leo.plagnol@ijclab.in2p3.fr *
* *
* Creation Date : January 2025 *
* Last update : *
*---------------------------------------------------------------------------*
* Decription: *
* This class hold Coaxial_Germanium Spectra *
* *
*---------------------------------------------------------------------------*
* Comment: *
* *
* *
*****************************************************************************/
// NPLib headers
#include "NPVSpectra.h"
#include "TCoaxial_GermaniumData.h"
#include "TCoaxial_GermaniumPhysics.h"
// Forward Declaration
class TCoaxial_GermaniumPhysics;
class TCoaxial_GermaniumSpectra : public VSpectra {
//////////////////////////////////////////////////////////////
// constructor and destructor
public:
TCoaxial_GermaniumSpectra();
TCoaxial_GermaniumSpectra(unsigned int NumberOfDetectors);
~TCoaxial_GermaniumSpectra();
//////////////////////////////////////////////////////////////
// Initialization methods
private:
void InitRawSpectra();
void InitPreTreatedSpectra();
void InitPhysicsSpectra();
//////////////////////////////////////////////////////////////
// Filling methods
public:
void FillRawSpectra(TCoaxial_GermaniumData*);
void FillPreTreatedSpectra(TCoaxial_GermaniumData*);
void FillPhysicsSpectra(TCoaxial_GermaniumPhysics*);
//////////////////////////////////////////////////////////////
// Detector parameters
private:
unsigned int fNumberOfDetectors;
};
#endif
add_custom_command(OUTPUT TPlastic_BEDOPhysicsDict.cxx COMMAND ../../scripts/build_dict.sh TPlastic_BEDOPhysics.h TPlastic_BEDOPhysicsDict.cxx TPlastic_BEDOPhysics.rootmap libNPPlastic_BEDO.dylib DEPENDS TPlastic_BEDOPhysics.h)
add_custom_command(OUTPUT TPlastic_BEDODataDict.cxx COMMAND ../../scripts/build_dict.sh TPlastic_BEDOData.h TPlastic_BEDODataDict.cxx TPlastic_BEDOData.rootmap libNPPlastic_BEDO.dylib DEPENDS TPlastic_BEDOData.h)
add_library(NPPlastic_BEDO SHARED TPlastic_BEDOSpectra.cxx TPlastic_BEDOData.cxx TPlastic_BEDOPhysics.cxx TPlastic_BEDODataDict.cxx TPlastic_BEDOPhysicsDict.cxx )
target_link_libraries(NPPlastic_BEDO ${ROOT_LIBRARIES} NPCore)
install(FILES TPlastic_BEDOData.h TPlastic_BEDOPhysics.h TPlastic_BEDOSpectra.h DESTINATION ${CMAKE_INCLUDE_OUTPUT_DIRECTORY})
/*****************************************************************************
* Copyright (C) 2009-2025 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: Léo Plagnol contact address: leo.plagnol@ijclab.in2p3.fr *
* *
* Creation Date : January 2025 *
* Last update : *
*---------------------------------------------------------------------------*
* Decription: *
* This class hold Plastic_BEDO Raw data *
* *
*---------------------------------------------------------------------------*
* Comment: *
* *
* *
*****************************************************************************/
#include "TPlastic_BEDOData.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
using namespace std;
ClassImp(TPlastic_BEDOData)
//////////////////////////////////////////////////////////////////////
TPlastic_BEDOData::TPlastic_BEDOData() {
}
//////////////////////////////////////////////////////////////////////
TPlastic_BEDOData::~TPlastic_BEDOData() {
}
//////////////////////////////////////////////////////////////////////
void TPlastic_BEDOData::Clear() {
// Energy
fPlastic_BEDO_E_DetectorNbr.clear();
fPlastic_BEDO_Energy.clear();
// Time
fPlastic_BEDO_T_DetectorNbr.clear();
fPlastic_BEDO_Time.clear();
}
//////////////////////////////////////////////////////////////////////
void TPlastic_BEDOData::Dump() const {
// This method is very useful for debuging and worth the dev.
cout << "XXXXXXXXXXXXXXXXXXXXXXXX New Event [TPlastic_BEDOData::Dump()] XXXXXXXXXXXXXXXXX" << endl;
// Energy
size_t mysize = fPlastic_BEDO_E_DetectorNbr.size();
cout << "Plastic_BEDO_E_Mult: " << mysize << endl;
for (size_t i = 0 ; i < mysize ; i++){
cout << "DetNbr: " << fPlastic_BEDO_E_DetectorNbr[i]
<< " Energy: " << fPlastic_BEDO_Energy[i];
}
// Time
mysize = fPlastic_BEDO_T_DetectorNbr.size();
cout << "Plastic_BEDO_T_Mult: " << mysize << endl;
for (size_t i = 0 ; i < mysize ; i++){
cout << "DetNbr: " << fPlastic_BEDO_T_DetectorNbr[i]
<< " Time: " << fPlastic_BEDO_Time[i];
}
}
#ifndef __Plastic_BEDODATA__
#define __Plastic_BEDODATA__
/*****************************************************************************
* Copyright (C) 2009-2025 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: Léo Plagnol contact address: leo.plagnol@ijclab.in2p3.fr *
* *
* Creation Date : January 2025 *
* Last update : *
*---------------------------------------------------------------------------*
* Decription: *
* This class hold Plastic_BEDO Raw data *
* *
*---------------------------------------------------------------------------*
* Comment: *
* *
* *
*****************************************************************************/
// STL
#include <vector>
using namespace std;
// ROOT
#include "TObject.h"
class TPlastic_BEDOData : public TObject {
//////////////////////////////////////////////////////////////
// data members are hold into vectors in order
// to allow multiplicity treatment
private:
// Energy
vector<UShort_t> fPlastic_BEDO_E_DetectorNbr;
vector<Double_t> fPlastic_BEDO_Energy;
// Time
vector<UShort_t> fPlastic_BEDO_T_DetectorNbr;
vector<Double_t> fPlastic_BEDO_Time;
//////////////////////////////////////////////////////////////
// Constructor and destructor
public:
TPlastic_BEDOData();
~TPlastic_BEDOData();
//////////////////////////////////////////////////////////////
// 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){
fPlastic_BEDO_E_DetectorNbr.push_back(DetNbr);
fPlastic_BEDO_Energy.push_back(Energy);
};//!
// Time
inline void SetTime(const UShort_t& DetNbr,const Double_t& Time) {
fPlastic_BEDO_T_DetectorNbr.push_back(DetNbr);
fPlastic_BEDO_Time.push_back(Time);
};//!
////////////////////// GETTERS ////////////////////////
// Energy
inline UShort_t GetMultEnergy() const
{return fPlastic_BEDO_E_DetectorNbr.size();}
inline UShort_t GetE_DetectorNbr(const unsigned int &i) const
{return fPlastic_BEDO_E_DetectorNbr[i];}//!
inline Double_t Get_Energy(const unsigned int &i) const
{return fPlastic_BEDO_Energy[i];}//!
// Time
inline UShort_t GetMultTime() const
{return fPlastic_BEDO_T_DetectorNbr.size();}
inline UShort_t GetT_DetectorNbr(const unsigned int &i) const
{return fPlastic_BEDO_T_DetectorNbr[i];}//!
inline Double_t Get_Time(const unsigned int &i) const
{return fPlastic_BEDO_Time[i];}//!
//////////////////////////////////////////////////////////////
// Required for ROOT dictionnary
ClassDef(TPlastic_BEDOData,1) // Plastic_BEDOData structure
};
#endif
/*****************************************************************************
* Copyright (C) 2009-2025 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: Léo Plagnol contact address: leo.plagnol@ijclab.in2p3.fr *
* *
* Creation Date : January 2025 *
* Last update : *
*---------------------------------------------------------------------------*
* Decription: *
* This class hold Plastic_BEDO Treated data *
* *
*---------------------------------------------------------------------------*
* Comment: *
* *
* *
*****************************************************************************/
#include "TPlastic_BEDOPhysics.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(TPlastic_BEDOPhysics)
///////////////////////////////////////////////////////////////////////////
TPlastic_BEDOPhysics::TPlastic_BEDOPhysics()
: m_EventData(new TPlastic_BEDOData),
m_PreTreatedData(new TPlastic_BEDOData),
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 TPlastic_BEDOPhysics::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 TPlastic_BEDOPhysics::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 TPlastic_BEDOPhysics::BuildSimplePhysicalEvent() {
BuildPhysicalEvent();
}
///////////////////////////////////////////////////////////////////////////
void TPlastic_BEDOPhysics::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 TPlastic_BEDOPhysics::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("Plastic_BEDO/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("Plastic_BEDO/TIME"+NPL::itoa(m_EventData->GetT_DetectorNbr(i)),m_EventData->Get_Time(i));
m_PreTreatedData->SetTime(m_EventData->GetT_DetectorNbr(i), Time);
}
}
///////////////////////////////////////////////////////////////////////////
void TPlastic_BEDOPhysics::ReadAnalysisConfig() {
bool ReadingStatus = false;
// path to file
string FileName = "./configs/ConfigPlastic_BEDO.dat";
// open analysis config file
ifstream AnalysisConfigFile;
AnalysisConfigFile.open(FileName.c_str());
if (!AnalysisConfigFile.is_open()) {
cout << " No ConfigPlastic_BEDO.dat found: Default parameter loaded for Analayis " << FileName << endl;
return;
}
cout << " Loading user parameter for Analysis from ConfigPlastic_BEDO.dat " << endl;
// Save it in a TAsciiFile
TAsciiFile* asciiConfig = RootOutput::getInstance()->GetAsciiFileAnalysisConfig();
asciiConfig->AppendLine("%%% ConfigPlastic_BEDO.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 = "ConfigPlastic_BEDO";
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 TPlastic_BEDOPhysics::Clear() {
DetectorNumber.clear();
Energy.clear();
Time.clear();
}
///////////////////////////////////////////////////////////////////////////
void TPlastic_BEDOPhysics::ReadConfiguration(NPL::InputParser parser) {
vector<NPL::InputBlock*> blocks = parser.GetAllBlocksWithToken("Plastic_BEDO");
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 << "//// Plastic_BEDO " << 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 << "//// Plastic_BEDO " << 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 TPlastic_BEDOPhysics::InitSpectra() {
m_Spectra = new TPlastic_BEDOSpectra(m_NumberOfDetectors);
}
///////////////////////////////////////////////////////////////////////////
void TPlastic_BEDOPhysics::FillSpectra() {
m_Spectra -> FillRawSpectra(m_EventData);
m_Spectra -> FillPreTreatedSpectra(m_PreTreatedData);
m_Spectra -> FillPhysicsSpectra(m_EventPhysics);
}
///////////////////////////////////////////////////////////////////////////
void TPlastic_BEDOPhysics::CheckSpectra() {
m_Spectra->CheckSpectra();
}
///////////////////////////////////////////////////////////////////////////
void TPlastic_BEDOPhysics::ClearSpectra() {
// To be done
}
///////////////////////////////////////////////////////////////////////////
map< string , TH1*> TPlastic_BEDOPhysics::GetSpectra() {
if(m_Spectra)
return m_Spectra->GetMapHisto();
else{
map< string , TH1*> empty;
return empty;
}
}
///////////////////////////////////////////////////////////////////////////
void TPlastic_BEDOPhysics::WriteSpectra() {
m_Spectra->WriteSpectra();
}
///////////////////////////////////////////////////////////////////////////
void TPlastic_BEDOPhysics::AddParameterToCalibrationManager() {
CalibrationManager* Cal = CalibrationManager::getInstance();
for (int i = 0; i < m_NumberOfDetectors; ++i) {
Cal->AddParameter("Plastic_BEDO", "D"+ NPL::itoa(i+1)+"_ENERGY","Plastic_BEDO_D"+ NPL::itoa(i+1)+"_ENERGY");
Cal->AddParameter("Plastic_BEDO", "D"+ NPL::itoa(i+1)+"_TIME","Plastic_BEDO_D"+ NPL::itoa(i+1)+"_TIME");
}
}
///////////////////////////////////////////////////////////////////////////
void TPlastic_BEDOPhysics::InitializeRootInputRaw() {
TChain* inputChain = RootInput::getInstance()->GetChain();
inputChain->SetBranchStatus("Plastic_BEDO", true );
inputChain->SetBranchAddress("Plastic_BEDO", &m_EventData );
}
///////////////////////////////////////////////////////////////////////////
void TPlastic_BEDOPhysics::InitializeRootInputPhysics() {
TChain* inputChain = RootInput::getInstance()->GetChain();
inputChain->SetBranchAddress("Plastic_BEDO", &m_EventPhysics);
}
///////////////////////////////////////////////////////////////////////////
void TPlastic_BEDOPhysics::InitializeRootOutput() {
TTree* outputTree = RootOutput::getInstance()->GetTree();
outputTree->Branch("Plastic_BEDO", "TPlastic_BEDOPhysics", &m_EventPhysics);
}
////////////////////////////////////////////////////////////////////////////////
// Construct Method to be pass to the DetectorFactory //
////////////////////////////////////////////////////////////////////////////////
NPL::VDetector* TPlastic_BEDOPhysics::Construct() {
return (NPL::VDetector*) new TPlastic_BEDOPhysics();
}
////////////////////////////////////////////////////////////////////////////////
// Registering the construct method to the factory //
////////////////////////////////////////////////////////////////////////////////
extern "C"{
class proxy_Plastic_BEDO{
public:
proxy_Plastic_BEDO(){
NPL::DetectorFactory::getInstance()->AddToken("Plastic_BEDO","Plastic_BEDO");
NPL::DetectorFactory::getInstance()->AddDetector("Plastic_BEDO",TPlastic_BEDOPhysics::Construct);
}
};
proxy_Plastic_BEDO p_Plastic_BEDO;
}
#ifndef TPlastic_BEDOPHYSICS_H
#define TPlastic_BEDOPHYSICS_H
/*****************************************************************************
* Copyright (C) 2009-2025 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: Léo Plagnol contact address: leo.plagnol@ijclab.in2p3.fr *
* *
* Creation Date : January 2025 *
* Last update : *
*---------------------------------------------------------------------------*
* Decription: *
* This class hold Plastic_BEDO 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 "TPlastic_BEDOData.h"
#include "TPlastic_BEDOSpectra.h"
#include "NPCalibrationManager.h"
#include "NPVDetector.h"
#include "NPInputParser.h"
// forward declaration
class TPlastic_BEDOSpectra;
class TPlastic_BEDOPhysics : public TObject, public NPL::VDetector {
//////////////////////////////////////////////////////////////
// constructor and destructor
public:
TPlastic_BEDOPhysics();
~TPlastic_BEDOPhysics() {};
//////////////////////////////////////////////////////////////
// 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 TPlastic_BEDOSpectra class
// instantiate the TPlastic_BEDOSpectra 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 Plastic_BEDO 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 TPlastic_BEDOData object to TPlastic_BEDOPhysics.
// needed for online analysis for example
void SetRawDataPointer(TPlastic_BEDOData* rawDataPointer) {m_EventData = rawDataPointer;}
// objects are not written in the TTree
private:
TPlastic_BEDOData* m_EventData; //!
TPlastic_BEDOData* m_PreTreatedData; //!
TPlastic_BEDOPhysics* m_EventPhysics; //!
// getters for raw and pre-treated data object
public:
TPlastic_BEDOData* GetRawData() const {return m_EventData;}
TPlastic_BEDOData* 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:
TPlastic_BEDOSpectra* m_Spectra; // !
// spectra getter
public:
map<string, TH1*> GetSpectra();
// Static constructor to be passed to the Detector Factory
public:
static NPL::VDetector* Construct();
ClassDef(TPlastic_BEDOPhysics,1) // Plastic_BEDOPhysics structure
};
#endif
/*****************************************************************************
* Copyright (C) 2009-2025 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: Léo Plagnol contact address: leo.plagnol@ijclab.in2p3.fr *
* *
* Creation Date : January 2025 *
* Last update : *
*---------------------------------------------------------------------------*
* Decription: *
* This class hold Plastic_BEDO Spectra *
* *
*---------------------------------------------------------------------------*
* Comment: *
* *
* *
*****************************************************************************/
// class header
#include "TPlastic_BEDOSpectra.h"
// STL
#include <iostream>
#include <string>
using namespace std;
// NPTool header
#include "NPOptionManager.h"
////////////////////////////////////////////////////////////////////////////////
TPlastic_BEDOSpectra::TPlastic_BEDOSpectra()
: fNumberOfDetectors(0) {
SetName("Plastic_BEDO");
}
////////////////////////////////////////////////////////////////////////////////
TPlastic_BEDOSpectra::TPlastic_BEDOSpectra(unsigned int NumberOfDetectors) {
if(NPOptionManager::getInstance()->GetVerboseLevel()>0)
cout << "************************************************" << endl
<< "TPlastic_BEDOSpectra : Initalizing control spectra for "
<< NumberOfDetectors << " Detectors" << endl
<< "************************************************" << endl ;
SetName("Plastic_BEDO");
fNumberOfDetectors = NumberOfDetectors;
InitRawSpectra();
InitPreTreatedSpectra();
InitPhysicsSpectra();
}
////////////////////////////////////////////////////////////////////////////////
TPlastic_BEDOSpectra::~TPlastic_BEDOSpectra() {
}
////////////////////////////////////////////////////////////////////////////////
void TPlastic_BEDOSpectra::InitRawSpectra() {
static string name;
for (unsigned int i = 0; i < fNumberOfDetectors; i++) { // loop on number of detectors
// Energy
name = "Plastic_BEDO"+NPL::itoa(i+1)+"_ENERGY_RAW";
AddHisto1D(name, name, 4096, 0, 16384, "Plastic_BEDO/RAW");
// Time
name = "Plastic_BEDO"+NPL::itoa(i+1)+"_TIME_RAW";
AddHisto1D(name, name, 4096, 0, 16384, "Plastic_BEDO/RAW");
} // end loop on number of detectors
}
////////////////////////////////////////////////////////////////////////////////
void TPlastic_BEDOSpectra::InitPreTreatedSpectra() {
static string name;
for (unsigned int i = 0; i < fNumberOfDetectors; i++) { // loop on number of detectors
// Energy
name = "Plastic_BEDO"+NPL::itoa(i+1)+"_ENERGY_CAL";
AddHisto1D(name, name, 500, 0, 25, "Plastic_BEDO/CAL");
// Time
name = "Plastic_BEDO"+NPL::itoa(i+1)+"_TIME_CAL";
AddHisto1D(name, name, 500, 0, 25, "Plastic_BEDO/CAL");
} // end loop on number of detectors
}
////////////////////////////////////////////////////////////////////////////////
void TPlastic_BEDOSpectra::InitPhysicsSpectra() {
static string name;
// Kinematic Plot
name = "Plastic_BEDO_ENERGY_TIME";
AddHisto2D(name, name, 500, 0, 500, 500, 0, 50, "Plastic_BEDO/PHY");
}
////////////////////////////////////////////////////////////////////////////////
void TPlastic_BEDOSpectra::FillRawSpectra(TPlastic_BEDOData* RawData) {
static string name;
static string family;
// Energy
unsigned int sizeE = RawData->GetMultEnergy();
for (unsigned int i = 0; i < sizeE; i++) {
name = "Plastic_BEDO"+NPL::itoa(RawData->GetE_DetectorNbr(i))+"_ENERGY_RAW";
family = "Plastic_BEDO/RAW";
FillSpectra(family,name,RawData->Get_Energy(i));
}
// Time
unsigned int sizeT = RawData->GetMultTime();
for (unsigned int i = 0; i < sizeT; i++) {
name = "Plastic_BEDO"+NPL::itoa(RawData->GetT_DetectorNbr(i))+"_TIME_RAW";
family = "Plastic_BEDO/RAW";
FillSpectra(family,name,RawData->Get_Time(i));
}
}
////////////////////////////////////////////////////////////////////////////////
void TPlastic_BEDOSpectra::FillPreTreatedSpectra(TPlastic_BEDOData* PreTreatedData) {
static string name;
static string family;
// Energy
unsigned int sizeE = PreTreatedData->GetMultEnergy();
for (unsigned int i = 0; i < sizeE; i++) {
name = "Plastic_BEDO"+NPL::itoa(PreTreatedData->GetE_DetectorNbr(i))+"_ENERGY_CAL";
family = "Plastic_BEDO/CAL";
FillSpectra(family,name,PreTreatedData->Get_Energy(i));
}
// Time
unsigned int sizeT = PreTreatedData->GetMultTime();
for (unsigned int i = 0; i < sizeT; i++) {
name = "Plastic_BEDO"+NPL::itoa(PreTreatedData->GetT_DetectorNbr(i))+"_TIME_CAL";
family = "Plastic_BEDO/CAL";
FillSpectra(family,name,PreTreatedData->Get_Time(i));
}
}
////////////////////////////////////////////////////////////////////////////////
void TPlastic_BEDOSpectra::FillPhysicsSpectra(TPlastic_BEDOPhysics* Physics) {
static string name;
static string family;
family= "Plastic_BEDO/PHY";
// Energy vs time
unsigned int sizeE = Physics->Energy.size();
for(unsigned int i = 0 ; i < sizeE ; i++){
name = "Plastic_BEDO_ENERGY_TIME";
FillSpectra(family,name,Physics->Energy[i],Physics->Time[i]);
}
}
#ifndef TPlastic_BEDOSPECTRA_H
#define TPlastic_BEDOSPECTRA_H
/*****************************************************************************
* Copyright (C) 2009-2025 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: Léo Plagnol contact address: leo.plagnol@ijclab.in2p3.fr *
* *
* Creation Date : January 2025 *
* Last update : *
*---------------------------------------------------------------------------*
* Decription: *
* This class hold Plastic_BEDO Spectra *
* *
*---------------------------------------------------------------------------*
* Comment: *
* *
* *
*****************************************************************************/
// NPLib headers
#include "NPVSpectra.h"
#include "TPlastic_BEDOData.h"
#include "TPlastic_BEDOPhysics.h"
// Forward Declaration
class TPlastic_BEDOPhysics;
class TPlastic_BEDOSpectra : public VSpectra {
//////////////////////////////////////////////////////////////
// constructor and destructor
public:
TPlastic_BEDOSpectra();
TPlastic_BEDOSpectra(unsigned int NumberOfDetectors);
~TPlastic_BEDOSpectra();
//////////////////////////////////////////////////////////////
// Initialization methods
private:
void InitRawSpectra();
void InitPreTreatedSpectra();
void InitPhysicsSpectra();
//////////////////////////////////////////////////////////////
// Filling methods
public:
void FillRawSpectra(TPlastic_BEDOData*);
void FillPreTreatedSpectra(TPlastic_BEDOData*);
void FillPhysicsSpectra(TPlastic_BEDOPhysics*);
//////////////////////////////////////////////////////////////
// Detector parameters
private:
unsigned int fNumberOfDetectors;
};
#endif
add_library(NPSCoaxial_Germanium SHARED Coaxial_Germanium.cc)
target_link_libraries(NPSCoaxial_Germanium NPSCore ${ROOT_LIBRARIES} ${Geant4_LIBRARIES} ${NPLib_LIBRARIES} -lNPCoaxial_Germanium)
/*****************************************************************************
* Copyright (C) 2009-2025 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: Léo Plagnol contact address: leo.plagnol@ijclab.in2p3.fr *
* *
* Creation Date : January 2025 *
* Last update : *
*---------------------------------------------------------------------------*
* Decription: *
* This class describe Coaxial_Germanium simulation *
* *
*---------------------------------------------------------------------------*
* Comment: *
* *
*****************************************************************************/
// C++ headers
#include <sstream>
#include <cmath>
#include <limits>
//G4 Geometry object
#include "G4Tubs.hh"
#include "G4Box.hh"
#include "G4Polycone.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 "Coaxial_Germanium.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 Coaxial_Germanium_NS{
// Energy and time Resolution
const double EnergyThreshold = 0.01*MeV;
const double ResoTime = 0*ns ;
const double ResoEnergy = 1e-9*keV ;
const string Material_Shell = "Al";
const double radii_internal[7] = {0 , 65/2.*mm-1*mm, 90/2*mm-1*mm, 90/2*mm-1*mm, 90/2*mm-1*mm, 222/2.*mm-1*mm, 0. };
const double radii_external[7] = {65/2.*mm, 65/2.*mm , 90/2.*mm , 90/2.*mm , 222/2.*mm , 222/2.*mm , 222/2.*mm };
const double length_external[7] = {0 , 0 , 100*mm , 450*mm , 450*mm , 700*mm , 700*mm };
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
// Coaxial_Germanium Specific Method
Coaxial_Germanium::Coaxial_Germanium(){
m_Event = new TCoaxial_GermaniumData() ;
m_Coaxial_GermaniumScorer = 0;
}
Coaxial_Germanium::~Coaxial_Germanium(){
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Coaxial_Germanium::AddDetector(G4ThreeVector POS){
// 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());
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Coaxial_Germanium::AddDetector(double R, double Theta, double Phi){
m_R.push_back(R);
m_Theta.push_back(Theta);
m_Phi.push_back(Phi);
}
G4LogicalVolume* Coaxial_Germanium::BuildDetector(G4int DetNumber, G4ThreeVector Det_pos, G4RotationMatrix* Det_rot, G4LogicalVolume* world){
// Materials
G4Material* DetectorMaterial = MaterialManager::getInstance()->GetMaterialFromLibrary(Coaxial_Germanium_NS::Material_Shell);
G4Material* m_MaterialVacuum = MaterialManager::getInstance()->GetMaterialFromLibrary("Vacuum");
G4Material* m_MaterialCarbon = MaterialManager::getInstance()->GetMaterialFromLibrary("C");
G4Material* m_MaterialGermanium = MaterialManager::getInstance()->GetMaterialFromLibrary("Germanium");
G4VisAttributes* light_GreyAtt = new G4VisAttributes(G4Colour(0.5, 0.5, 0.5, 0.7));
G4VisAttributes* RedAtt = new G4VisAttributes(G4Colour(1.0, 0.0, 0.0, 0.6));
G4VisAttributes* GreenAtt = new G4VisAttributes(G4Colour(0.0, 1.0, 0.0, 0.6));
// Global volume
// Origin axis at the front of detector
G4Tubs* solidCoaxial_Germanium = new G4Tubs("solidCoaxial_Germanium", 0, 25, 720*0.5*mm, 0, 360*deg);
G4LogicalVolume* logicCoaxial_Germanium = new G4LogicalVolume(solidCoaxial_Germanium, m_MaterialVacuum, "logicCoaxial_Germanium", 0, 0);
new G4PVPlacement(G4Transform3D(*Det_rot, Det_pos), logicCoaxial_Germanium, "Coaxial_Germanium", world, false, DetNumber);
logicCoaxial_Germanium->SetVisAttributes(G4VisAttributes::GetInvisible());
// Enveloppe
G4Polycone* Coaxial_Germanium_Cyl = new G4Polycone("Coaxial_Germanium_Cyl", 0, 360*deg, 7, Coaxial_Germanium_NS::length_external, Coaxial_Germanium_NS::radii_internal, Coaxial_Germanium_NS::radii_external);
G4LogicalVolume* vol_Coaxial_Germanium = new G4LogicalVolume(Coaxial_Germanium_Cyl, DetectorMaterial, "logic_Coaxial_Germanium_Cyl", 0, 0, 0);
G4ThreeVector Coaxial_Germanium_cyl_Pos = G4ThreeVector(0, 0, 0);
new G4PVPlacement(0, Coaxial_Germanium_cyl_Pos, vol_Coaxial_Germanium, "Coaxial_Germanium_cyl", logicCoaxial_Germanium, false, DetNumber);
vol_Coaxial_Germanium->SetVisAttributes(light_GreyAtt);
// Germanium crystal
G4Tubs* Coaxial_Germanium_crys = new G4Tubs("Coaxial_Germanium_crys",0 , 13*mm, 10.2*0.5*mm, 0, 360*deg);
G4LogicalVolume* vol_crys = new G4LogicalVolume(Coaxial_Germanium_crys, m_MaterialGermanium, "logic_Coaxial_Germanium_crys", 0, 0, 0);
G4ThreeVector crys_Pos = G4ThreeVector(0, 0, 0.6*1.5*mm+11*0.5*mm);
new G4PVPlacement(0, crys_Pos, vol_crys, "Coaxial_Germanium_crys", logicCoaxial_Germanium, false, DetNumber);
vol_crys->SetVisAttributes(RedAtt);
vol_crys->SetSensitiveDetector(m_Coaxial_GermaniumScorer);
return vol_Coaxial_Germanium;
}
//....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 Coaxial_Germanium::ReadConfiguration(NPL::InputParser parser){
vector<NPL::InputBlock*> blocks = parser.GetAllBlocksWithToken("Coaxial_Germanium");
if(NPOptionManager::getInstance()->GetVerboseLevel())
cout << "//// " << blocks.size() << " detectors found " << endl;
vector<string> cart = {"POS"};
vector<string> sphe = {"R","Theta","Phi"};
for(unsigned int i = 0 ; i < blocks.size() ; i++){
if(blocks[i]->HasTokenList(cart)){
if(NPOptionManager::getInstance()->GetVerboseLevel())
cout << endl << "//// Coaxial_Germanium " << i+1 << endl;
G4ThreeVector Pos = NPS::ConvertVector(blocks[i]->GetTVector3("POS","mm"));
AddDetector(Pos);
}
else if(blocks[i]->HasTokenList(sphe)){
if(NPOptionManager::getInstance()->GetVerboseLevel())
cout << endl << "//// Coaxial_Germanium " << i+1 << endl;
double R = blocks[i]->GetDouble("R","mm");
double Theta = blocks[i]->GetDouble("Theta","deg");
double Phi = blocks[i]->GetDouble("Phi","deg");
AddDetector(R,Theta,Phi);
}
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 Coaxial_Germanium::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()*Coaxial_Germanium_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);
BuildDetector(i+1, Det_pos, Rot, world);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
// Add Detector branch to the EventTree.
// Called After DetecorConstruction::AddDetector Method
void Coaxial_Germanium::InitializeRootOutput(){
RootOutput *pAnalysis = RootOutput::getInstance();
TTree *pTree = pAnalysis->GetTree();
if(!pTree->FindBranch("Coaxial_Germanium")){
pTree->Branch("Coaxial_Germanium", "TCoaxial_GermaniumData", &m_Event) ;
}
pTree->SetBranchAddress("Coaxial_Germanium", &m_Event) ;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
// Read sensitive part and fill the Root tree.
// Called at in the EventAction::EndOfEventAvtion
void Coaxial_Germanium::ReadSensitive(const G4Event* ){
m_Event->Clear();
///////////
// Calorimeter scorer
CalorimeterScorers::PS_Calorimeter* Scorer= (CalorimeterScorers::PS_Calorimeter*) m_Coaxial_GermaniumScorer->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),Coaxial_Germanium_NS::ResoEnergy);
if(Energy>Coaxial_Germanium_NS::EnergyThreshold){
double Time = RandGauss::shoot(Scorer->GetTime(i),Coaxial_Germanium_NS::ResoTime);
int DetectorNbr = level[0];
m_Event->SetEnergy(DetectorNbr,Energy);
m_Event->SetTime(DetectorNbr,Time);
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
////////////////////////////////////////////////////////////////
void Coaxial_Germanium::InitializeScorers() {
// This check is necessary in case the geometry is reloaded
bool already_exist = false;
m_Coaxial_GermaniumScorer = CheckScorer("Coaxial_GermaniumScorer",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_Coaxial_GermaniumScorer->RegisterPrimitive(Calorimeter);
m_Coaxial_GermaniumScorer->RegisterPrimitive(Interaction);
G4SDManager::GetSDMpointer()->AddNewDetector(m_Coaxial_GermaniumScorer) ;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
////////////////////////////////////////////////////////////////////////////////
// Construct Method to be pass to the DetectorFactory //
////////////////////////////////////////////////////////////////////////////////
NPS::VDetector* Coaxial_Germanium::Construct(){
return (NPS::VDetector*) new Coaxial_Germanium();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
////////////////////////////////////////////////////////////////////////////////
// Registering the construct method to the factory //
////////////////////////////////////////////////////////////////////////////////
extern"C" {
class proxy_nps_Coaxial_Germanium{
public:
proxy_nps_Coaxial_Germanium(){
NPS::DetectorFactory::getInstance()->AddToken("Coaxial_Germanium","Coaxial_Germanium");
NPS::DetectorFactory::getInstance()->AddDetector("Coaxial_Germanium",Coaxial_Germanium::Construct);
}
};
proxy_nps_Coaxial_Germanium p_nps_Coaxial_Germanium;
}
#ifndef Coaxial_Germanium_h
#define Coaxial_Germanium_h 1
/*****************************************************************************
* Copyright (C) 2009-2025 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: Léo Plagnol contact address: leo.plagnol@ijclab.in2p3.fr *
* *
* Creation Date : January 2025 *
* Last update : *
*---------------------------------------------------------------------------*
* Decription: *
* This class describe Coaxial_Germanium 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 "TCoaxial_GermaniumData.h"
#include "NPInputParser.h"
class Coaxial_Germanium : public NPS::VDetector{
////////////////////////////////////////////////////
/////// Default Constructor and Destructor /////////
////////////////////////////////////////////////////
public:
Coaxial_Germanium() ;
virtual ~Coaxial_Germanium() ;
////////////////////////////////////////////////////
/////// Specific Function of this Class ///////////
////////////////////////////////////////////////////
public:
// Cartesian
void AddDetector(G4ThreeVector POS);
// Spherical
void AddDetector(double R,double Theta,double Phi);
G4LogicalVolume* BuildDetector(G4int, G4ThreeVector, G4RotationMatrix*, G4LogicalVolume*);
private:
////////////////////////////////////////////////////
////// 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_Coaxial_GermaniumScorer ;
////////////////////////////////////////////////////
///////////Event class to store Data////////////////
////////////////////////////////////////////////////
private:
TCoaxial_GermaniumData* m_Event ;
////////////////////////////////////////////////////
///////////////Private intern Data//////////////////
////////////////////////////////////////////////////
private: // Geometry
// Detector Coordinate
vector<double> m_R;
vector<double> m_Theta;
vector<double> m_Phi;
// Needed for dynamic loading of the library
public:
static NPS::VDetector* Construct();
};
#endif
add_library(NPSPlastic_BEDO SHARED Plastic_BEDO.cc)
target_link_libraries(NPSPlastic_BEDO NPSCore ${ROOT_LIBRARIES} ${Geant4_LIBRARIES} ${NPLib_LIBRARIES} -lNPPlastic_BEDO)
/*****************************************************************************
* Copyright (C) 2009-2025 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: Léo Plagnol contact address: leo.plagnol@ijclab.in2p3.fr *
* *
* Creation Date : January 2025 *
* Last update : *
*---------------------------------------------------------------------------*
* Decription: *
* This class describe Plastic_BEDO 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 "Plastic_BEDO.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 Plastic_BEDO_NS{
// Energy and time Resolution
const double EnergyThreshold = 0.1*MeV;
const double ResoTime = 4.5*ns ;
const double ResoEnergy = 1.0*MeV ;
const double Radius = 30*mm ;
const double Thickness = 2*mm ;
const double Length = 100*mm ;
const string Material = "BC400";
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
// Plastic_BEDO Specific Method
Plastic_BEDO::Plastic_BEDO(){
m_Event = new TPlastic_BEDOData() ;
m_Plastic_BEDOScorer = 0;
m_SquareDetector = 0;
m_CylindricalDetector = 0;
// RGB Color + Transparency
m_VisSquare = new G4VisAttributes(G4Colour(0, 1, 0, 0.5));
m_VisCylinder = new G4VisAttributes(G4Colour(0, 0, 1, 0.5));
}
Plastic_BEDO::~Plastic_BEDO(){
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Plastic_BEDO::AddDetector(G4ThreeVector POS){
// 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());
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Plastic_BEDO::AddDetector(double R, double Theta, double Phi){
m_R.push_back(R);
m_Theta.push_back(Theta);
m_Phi.push_back(Phi);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
G4LogicalVolume* Plastic_BEDO::BuildCylindricalDetector(){
if(!m_CylindricalDetector){
G4Tubs* tub = new G4Tubs("Plastic_BEDO",Plastic_BEDO_NS::Radius-Plastic_BEDO_NS::Thickness,Plastic_BEDO_NS::Radius,Plastic_BEDO_NS::Length*0.5,0,360*deg);
G4Material* DetectorMaterial = MaterialManager::getInstance()->GetMaterialFromLibrary(Plastic_BEDO_NS::Material);
m_CylindricalDetector = new G4LogicalVolume(tub,DetectorMaterial,"logic_Plastic_BEDO_tub",0,0,0);
m_CylindricalDetector->SetVisAttributes(m_VisSquare);
m_CylindricalDetector->SetSensitiveDetector(m_Plastic_BEDOScorer);
}
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 Plastic_BEDO::ReadConfiguration(NPL::InputParser parser){
vector<NPL::InputBlock*> blocks = parser.GetAllBlocksWithToken("Plastic_BEDO");
if(NPOptionManager::getInstance()->GetVerboseLevel())
cout << "//// " << blocks.size() << " detectors found " << endl;
vector<string> cart = {"POS"};
vector<string> sphe = {"R","Theta","Phi"};
for(unsigned int i = 0 ; i < blocks.size() ; i++){
if(blocks[i]->HasTokenList(cart)){
if(NPOptionManager::getInstance()->GetVerboseLevel())
cout << endl << "//// Plastic_BEDO " << i+1 << endl;
G4ThreeVector Pos = NPS::ConvertVector(blocks[i]->GetTVector3("POS","mm"));
AddDetector(Pos);
}
else if(blocks[i]->HasTokenList(sphe)){
if(NPOptionManager::getInstance()->GetVerboseLevel())
cout << endl << "//// Plastic_BEDO " << i+1 << endl;
double R = blocks[i]->GetDouble("R","mm");
double Theta = blocks[i]->GetDouble("Theta","deg");
double Phi = blocks[i]->GetDouble("Phi","deg");
AddDetector(R,Theta,Phi);
}
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 Plastic_BEDO::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()*Plastic_BEDO_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);
new G4PVPlacement(G4Transform3D(*Rot,Det_pos),
BuildCylindricalDetector(),
"Plastic_BEDO",world,false,i+1);
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
// Add Detector branch to the EventTree.
// Called After DetecorConstruction::AddDetector Method
void Plastic_BEDO::InitializeRootOutput(){
RootOutput *pAnalysis = RootOutput::getInstance();
TTree *pTree = pAnalysis->GetTree();
if(!pTree->FindBranch("Plastic_BEDO")){
pTree->Branch("Plastic_BEDO", "TPlastic_BEDOData", &m_Event) ;
}
pTree->SetBranchAddress("Plastic_BEDO", &m_Event) ;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
// Read sensitive part and fill the Root tree.
// Called at in the EventAction::EndOfEventAvtion
void Plastic_BEDO::ReadSensitive(const G4Event* ){
m_Event->Clear();
///////////
// Calorimeter scorer
CalorimeterScorers::PS_Calorimeter* Scorer= (CalorimeterScorers::PS_Calorimeter*) m_Plastic_BEDOScorer->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),Plastic_BEDO_NS::ResoEnergy);
if(Energy>Plastic_BEDO_NS::EnergyThreshold){
double Time = RandGauss::shoot(Scorer->GetTime(i),Plastic_BEDO_NS::ResoTime);
int DetectorNbr = level[0];
m_Event->SetEnergy(DetectorNbr,Energy);
m_Event->SetTime(DetectorNbr,Time);
}
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
////////////////////////////////////////////////////////////////
void Plastic_BEDO::InitializeScorers() {
// This check is necessary in case the geometry is reloaded
bool already_exist = false;
m_Plastic_BEDOScorer = CheckScorer("Plastic_BEDOScorer",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_Plastic_BEDOScorer->RegisterPrimitive(Calorimeter);
m_Plastic_BEDOScorer->RegisterPrimitive(Interaction);
G4SDManager::GetSDMpointer()->AddNewDetector(m_Plastic_BEDOScorer) ;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
////////////////////////////////////////////////////////////////////////////////
// Construct Method to be pass to the DetectorFactory //
////////////////////////////////////////////////////////////////////////////////
NPS::VDetector* Plastic_BEDO::Construct(){
return (NPS::VDetector*) new Plastic_BEDO();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
////////////////////////////////////////////////////////////////////////////////
// Registering the construct method to the factory //
////////////////////////////////////////////////////////////////////////////////
extern"C" {
class proxy_nps_Plastic_BEDO{
public:
proxy_nps_Plastic_BEDO(){
NPS::DetectorFactory::getInstance()->AddToken("Plastic_BEDO","Plastic_BEDO");
NPS::DetectorFactory::getInstance()->AddDetector("Plastic_BEDO",Plastic_BEDO::Construct);
}
};
proxy_nps_Plastic_BEDO p_nps_Plastic_BEDO;
}
#ifndef Plastic_BEDO_h
#define Plastic_BEDO_h 1
/*****************************************************************************
* Copyright (C) 2009-2025 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: Léo Plagnol contact address: leo.plagnol@ijclab.in2p3.fr *
* *
* Creation Date : January 2025 *
* Last update : *
*---------------------------------------------------------------------------*
* Decription: *
* This class describe Plastic_BEDO 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 "TPlastic_BEDOData.h"
#include "NPInputParser.h"
class Plastic_BEDO : public NPS::VDetector{
////////////////////////////////////////////////////
/////// Default Constructor and Destructor /////////
////////////////////////////////////////////////////
public:
Plastic_BEDO() ;
virtual ~Plastic_BEDO() ;
////////////////////////////////////////////////////
/////// Specific Function of this Class ///////////
////////////////////////////////////////////////////
public:
// Cartesian
void AddDetector(G4ThreeVector POS);
// Spherical
void AddDetector(double R,double Theta,double Phi);
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_Plastic_BEDOScorer ;
////////////////////////////////////////////////////
///////////Event class to store Data////////////////
////////////////////////////////////////////////////
private:
TPlastic_BEDOData* 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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment