diff --git a/.gitignore b/.gitignore index 24e2f39cb8a20ed35b65c0643d4c4add10be10e3..82cab3c8e24b5ad7fa50a288b00295e2337bcc3a 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,7 @@ Projects/T40/*cxx Inputs/EnergyLoss/*.G4table Inputs/CrossSection/G4XS* Inputs/CrossSection/*.C +Inputs/CrossSection/*.dat .ls_return Documentation/user_guide.log *.bbl diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5d398c4544489c9a56d128c70b38072f9e1ca12b..563218f68294460f2860bdccdae2d7494d610ddb 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -23,7 +23,7 @@ building-NPLib: - NPLib/bin - NPLib/ClassList.txt - NPLib/NPLibConfig.cmake - expire_in: 1 hour + expire_in: 2 hour building-NPSimulation: stage: build-NPSimulation @@ -40,7 +40,7 @@ building-NPSimulation: - NPSimulation/include - NPSimulation/bin - NPSimulation/ressources - expire_in: 1 hour + expire_in: 2 hour testing: stage: test diff --git a/Examples/Example1/Analysis.cxx b/Examples/Example1/Analysis.cxx index fa8554aebb8d4a91f48286322f34a9f005aa5fbf..0a60fe37dc998bf3977f6574983f3a109b90a94f 100644 --- a/Examples/Example1/Analysis.cxx +++ b/Examples/Example1/Analysis.cxx @@ -75,6 +75,9 @@ void Analysis::TreatEvent(){ OriginalELab = ReactionConditions->GetKineticEnergy(0); OriginalThetaLab = ReactionConditions->GetTheta(0); OriginalBeamEnergy = ReactionConditions->GetBeamEnergy(); + ReactionVertexX = ReactionConditions->GetVertexPositionX(); + ReactionVertexY = ReactionConditions->GetVertexPositionY(); + ReactionVertexZ = ReactionConditions->GetVertexPositionZ(); // Get the Init information on beam position and energy // and apply by hand the experimental resolution // This is because the beam diagnosis are not simulated @@ -207,6 +210,9 @@ void Analysis::InitOutputBranch() { RootOutput::getInstance()->GetTree()->Branch("OriginalELab",&OriginalELab,"OriginalELab/D"); RootOutput::getInstance()->GetTree()->Branch("OriginalThetaLab",&OriginalThetaLab,"OriginalThetaLab/D"); RootOutput::getInstance()->GetTree()->Branch("OriginalBeamEnergy",&OriginalBeamEnergy,"OriginalBeamEnergy/D"); + RootOutput::getInstance()->GetTree()->Branch("ReactionVertexX",&ReactionVertexX,"ReactionVertexX/D"); + RootOutput::getInstance()->GetTree()->Branch("ReactionVertexY",&ReactionVertexY,"ReactionVertexY/D"); + RootOutput::getInstance()->GetTree()->Branch("ReactionVertexZ",&ReactionVertexZ,"ReactionVertexZ/D"); } //////////////////////////////////////////////////////////////////////////////// diff --git a/Examples/Example1/Analysis.h b/Examples/Example1/Analysis.h index 908a9f782c1812208524ef2cab6eae4dde6b4de7..7c2408efc4df64191df2b28f36793f17c080017b 100644 --- a/Examples/Example1/Analysis.h +++ b/Examples/Example1/Analysis.h @@ -54,6 +54,9 @@ class Analysis: public NPL::VAnalysis{ double OriginalELab; double OriginalThetaLab; double OriginalBeamEnergy; + double ReactionVertexX; + double ReactionVertexY; + double ReactionVertexZ; NPL::Reaction* He10Reaction; // intermediate variable diff --git a/Examples/Example1/ShowResults.C b/Examples/Example1/ShowResults.C index 8ea68944e989e3f7845c980a10f7837f31c3488e..3c8f9dfa9bdf91acea8e3538dee8f460449ab6a3 100644 --- a/Examples/Example1/ShowResults.C +++ b/Examples/Example1/ShowResults.C @@ -86,7 +86,7 @@ void ShowResults(){ f->SetNpx(1000); TCanvas* c2 = new TCanvas("Simulated","Simulated",600,0,600,600); - c2->Divide(2,2); + c2->Divide(2,3); c2->cd(1); chain->Draw("OriginalELab:OriginalThetaLab>>hS(1000,0,90,1000,0,30)","","col"); @@ -110,6 +110,7 @@ void ShowResults(){ TLine* lT = new TLine(0,0,90,90); lT->Draw(); + c2->cd(4); chain->Draw("OriginalBeamEnergy:BeamEnergy>>hS4(1000,500,600,1000,500,600)","BeamEnergy>0","col"); TH1F* hS4 = (TH1F*) gDirectory->FindObjectAny("hS4"); @@ -120,5 +121,16 @@ void ShowResults(){ lB->Draw(); + c2->cd(5); + chain->Draw("ReactionVertexY:ReactionVertexX>>hVXY(1000,-20,20,1000,-20,20)","","col"); + TH2F* hVXY = (TH2F*) gDirectory->FindObjectAny("hVXY"); + hVXY->GetYaxis()->SetTitle("Reaction vertex Y (mm)"); + hVXY->GetXaxis()->SetTitle("Reaction vertex X (mm)"); + + c2->cd(6); + chain->Draw("ReactionVertexX:ReactionVertexZ*1000.>>hVXZ(1000,-15,15,1000,-20,20)","","col"); + TH2F* hVXZ = (TH2F*) gDirectory->FindObjectAny("hVXZ"); + hVXZ->GetZaxis()->SetTitle("Reaction vertex X (mm)"); + hVXZ->GetXaxis()->SetTitle("Reaction vertex Z (um)"); } diff --git a/Examples/Example1/run.mac b/Examples/Example1/run.mac index 8eec34f7c0cc1911bbafaa6e92961e0836d874ba..b379ed9bcf78d80c4a29d004189059437aaa84d3 100644 --- a/Examples/Example1/run.mac +++ b/Examples/Example1/run.mac @@ -1 +1 @@ -/run/beamOn 1000 +/run/beamOn 10000 diff --git a/Examples/Example1/sim.sh b/Examples/Example1/sim.sh new file mode 100755 index 0000000000000000000000000000000000000000..561a386a8ee24fc95ae23f21b4c9e7881b5c3a76 --- /dev/null +++ b/Examples/Example1/sim.sh @@ -0,0 +1,3 @@ +npsimulation -D Example1.detector -E Example1.reaction -O Example1 -B run.mac +npanalysis --last-sim -O Example1 +root ShowResults.C diff --git a/Examples/Example5/CheckSimu.C b/Examples/Example5/CheckSimu.C index 188924f8734171aba8e62f958fb976e725385b07..9af4178999470a32d7030a245483eef2b4d5d3bf 100644 --- a/Examples/Example5/CheckSimu.C +++ b/Examples/Example5/CheckSimu.C @@ -77,7 +77,7 @@ void CheckSimu(const char * fname = "Example5"){ TH2F *hEmE1VsE2 = new TH2F("hEmE1VsE2", " E1 VS E2 (reaction frame)", 300, 0, 300,300,0,300); TH2F *hEmTheta1VsTheta2 = new TH2F("hEmTheta1VsTheta2", " Theta1 VS Theta2 (reaction frame)", 360, 0, 90,360,0,90); - TH2F *hEmPhi1VsPhi2 = new TH2F("hEmPhi1VsPhi2", " Phi1 VS Phi2 (reaction frame)", 360, 0, 360,360,0,360); + TH2F *hEmPhi1VsPhi2 = new TH2F("hEmPhi1VsPhi2", " Phi1 VS Phi2 (reaction frame)", 360, -180, 180,360,-180,180); // Read the TTree Int_t nentries = tree->GetEntries(); diff --git a/Inputs/EventGenerator/Example1.reaction b/Inputs/EventGenerator/Example1.reaction index 2461a6e242fd81cbbffbee76be42f21a82f03038..4eb8f8ee2fa5c39f0b4f555f9b8372cda2d276c8 100644 --- a/Inputs/EventGenerator/Example1.reaction +++ b/Inputs/EventGenerator/Example1.reaction @@ -34,12 +34,12 @@ TwoBodyReaction ShootHeavy= 1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%Decay 10He -% Daughter= 8He n n -% ExcitationEnergy= 0 0 0 MeV -% Threshold= 0 MeV -% BranchingRatio= 0.5 -% LifeTime= 0 ns -% Shoot= 1 1 1 +Decay 10He + Daughter= 8He n n + ExcitationEnergy= 0 0 0 MeV + Threshold= 0 MeV + BranchingRatio= 0.5 + LifeTime= 0 ns + Shoot= 1 1 1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/NPLib/CMakeLists.txt b/NPLib/CMakeLists.txt index 7d54fcd7ca875a2b8a4c2d909331265e4d30ea76..dceaa08a0feade1d72f9625edf8ab45af486b964 100644 --- a/NPLib/CMakeLists.txt +++ b/NPLib/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.8) +cmake_minimum_required (VERSION 3.0) include(CheckCXXCompilerFlag) project(NPLib CXX) set(CMAKE_BUILD_TYPE Release) diff --git a/NPLib/Core/NPCalibrationManager.cxx b/NPLib/Core/NPCalibrationManager.cxx index b998df20471f7609fd061bda7b49d667fa545e82..45864d6e07e8a68dd24cb06ce34cf03d864abf5c 100644 --- a/NPLib/Core/NPCalibrationManager.cxx +++ b/NPLib/Core/NPCalibrationManager.cxx @@ -24,6 +24,7 @@ #include "TAsciiFile.h" #include "RootOutput.h" #include "NPCore.h" +#include "TRandom.h" // STL #include <cstdlib> #include <limits> @@ -199,7 +200,7 @@ void CalibrationManager::LoadParameterFromFile(){ } ////////////////////////////////////////////////////////////////// -double CalibrationManager::ApplyCalibration(const std::string& ParameterPath , const double& RawValue) const { +double CalibrationManager::ApplyCalibration(const std::string& ParameterPath , const double& RawValue, double random) const { std::map< std::string , std::vector<double> >::const_iterator it ; static std::map< std::string , std::vector<double> >::const_iterator ite = fCalibrationCoeff.end(); @@ -208,24 +209,29 @@ double CalibrationManager::ApplyCalibration(const std::string& ParameterPath , c it = fCalibrationCoeff.find(ParameterPath) ; // If the find methods return the end iterator it's mean the parameter was not found if(it == ite ){ -//by Shuya 170222 -//std::cout << ParameterPath << "!" << std::endl; return RawValue ; } + double val ; + if(random){ + val=RawValue + gRandom->Uniform(random); + } + else + val=RawValue; + // The std::vector size give the degree of calibration // We just apply the coeff it->second and returned the calibrated value double CalibratedValue = 0 ; unsigned int mysize = it->second.size(); for(unsigned int i = 0 ; i < mysize ; i++){ - CalibratedValue += it->second[i]*pow(RawValue, (double)i); + CalibratedValue += it->second[i]*pow(val, (double)i); } return CalibratedValue ; } ////////////////////////////////////////////////////////////////// -double CalibrationManager::ApplyCalibrationDebug(const std::string& ParameterPath , const double& RawValue) const{ +double CalibrationManager::ApplyCalibrationDebug(const std::string& ParameterPath , const double& RawValue, double random) const{ std::map< std::string , std::vector<double> >::const_iterator it ; static std::map< std::string , std::vector<double> >::const_iterator ite = fCalibrationCoeff.end(); @@ -239,9 +245,17 @@ double CalibrationManager::ApplyCalibrationDebug(const std::string& ParameterPat return RawValue ; } + double val ; + if(random){ + val=RawValue + gRandom->Uniform(random); + } + else + val=RawValue; + + // Else we take the second part of the element (first is index, ie: parameter path) // Second is the std::vector of Coeff - std::cout << it->first << " : raw = " << RawValue << " coeff = " ; + std::cout << it->first << " : raw = " << RawValue << " randomize = " << val << " coeff = " ; std::vector<double> Coeff = it->second ; // The std::vector size give the degree of calibration diff --git a/NPLib/Core/NPCalibrationManager.h b/NPLib/Core/NPCalibrationManager.h index 4ea2fd5cef5e3bb3e0e21f5bdbfbf1a8cb9899fb..b1981418f56748d1140b78b2c2ffb53f2db19683 100644 --- a/NPLib/Core/NPCalibrationManager.h +++ b/NPLib/Core/NPCalibrationManager.h @@ -56,10 +56,10 @@ class CalibrationManager{ // call like : myCalibrationManager->ApplyCalibration( "MUST2/Telescope5_Si_X38_E" , RawEnergy ) // return the Calibrated value - double ApplyCalibration (const std::string& ParameterPath , const double& RawValue) const ; + double ApplyCalibration (const std::string& ParameterPath , const double& RawValue, double random=0) const ; double ApplyResistivePositionCalibration (const std::string& ParameterPath , const double& RawValue) const ; // Same but with debug information outputs - double ApplyCalibrationDebug (const std::string& ParameterPath , const double& RawValue) const ; + double ApplyCalibrationDebug (const std::string& ParameterPath , const double& RawValue, double random=0) const ; double ApplyResistivePositionCalibrationDebug (const std::string& ParameterPath , const double& RawValue) const ; bool ApplyThreshold (const std::string& ParameterPath, const double& RawValue) const ; diff --git a/NPLib/Core/NPInputParser.cxx b/NPLib/Core/NPInputParser.cxx index 606e2d2071a14aef6b7ac265644d8057b692346f..13196d0047e4e9a05893343a1b4c9c36d1c11161 100644 --- a/NPLib/Core/NPInputParser.cxx +++ b/NPLib/Core/NPInputParser.cxx @@ -392,7 +392,7 @@ void NPL::InputParser::TreatAliases(){ unsigned int size = m_Block[b]->GetSize(); size_t pos; // In place case loop over each value and replace them - if(action=="Inplace"){ + if(action=="Replace"){ for(unsigned int v = 0 ; v < size ; v++){ while((pos=m_Block[b]->GetValue(v).find(name))!=std::string::npos){ std::string val = m_Block[b]->GetValue(v); @@ -402,7 +402,7 @@ void NPL::InputParser::TreatAliases(){ } } - else if (action=="Split"){ + else if (action=="Copy"){ bool check = false; // first pass identify if the block use an alias for(unsigned int v = 0 ; v < size ; v++){ diff --git a/NPLib/Core/NPOptionManager.cxx b/NPLib/Core/NPOptionManager.cxx index c4e1573dcac0485d213d57210bd726d570ced8c7..8a42e82e6da5d3cd815e1e445b31f6aa994b0583 100644 --- a/NPLib/Core/NPOptionManager.cxx +++ b/NPLib/Core/NPOptionManager.cxx @@ -168,6 +168,8 @@ void NPOptionManager::ReadTheInputArgument(int argc, char** argv){ else if (argument == "--circular") {fCircularTree = true;} + else if (argument == "--definition" && argc >= i + 1) {std::string def= argv[++i];fDefinition.insert(def);} + else{ SendErrorAndExit(argument.c_str()); } @@ -401,6 +403,7 @@ void NPOptionManager::DisplayHelp(){ std::cout << "\t--event-generator -E <arg>\tSet arg as the event generator file" << std::endl ; std::cout << "\t--output -O <arg>\t\tSet arg as the Output File Name (output tree)" << std::endl ; std::cout << "\t--tree-name <arg>\t\tSet arg as the Output Tree Name " << std::endl ; + std::cout << "\t--definition <definition> \tAdd <definition> to the list of definition" << std::endl ; std::cout << "\t--verbose -V <arg>\t\tSet the verbose level, 0 for nothing, 1 for normal printout."<<std::endl; std::cout << "\t\t\t\t\tError and warning are not affected" << std::endl ; std::cout << std::endl << "NPAnalysis only:"<<std::endl; diff --git a/NPLib/Core/NPOptionManager.h b/NPLib/Core/NPOptionManager.h index fda9c185b270b0df64c98b18121c765951309ba3..a628d8fe0edaee7e1194d0f4ba62eaef47f8de28 100644 --- a/NPLib/Core/NPOptionManager.h +++ b/NPLib/Core/NPOptionManager.h @@ -26,6 +26,7 @@ // C++ headers #include <iostream> #include <string> +#include <set> class NPOptionManager{ public: @@ -116,7 +117,10 @@ class NPOptionManager{ void SetDetectorFile(const std::string& name) {fDetectorFileName = name;CheckDetectorConfiguration();} void SetRunToReadFile(const std::string& name) {fRunToReadFileName = name;} void SetVerboseLevel(int VerboseLevel) {fVerboseLevel = VerboseLevel;} - + + public: // user definition + bool HasDefinition(std::string def) {return(fDefinition.find(def)!=fDefinition.end());} + private: // default values std::string fDefaultReactionFileName; @@ -153,6 +157,7 @@ class NPOptionManager{ std::string fSharedLibExtension; // lib extension is platform dependent std::string fG4MacroPath; // Path to a geant4 macro to execute at start of nps bool fG4BatchMode; // Execute geant4 in batch mode, running the given macro + std::set<std::string> fDefinition; // a set of user defined definition }; #endif diff --git a/NPLib/Core/NPSystemOfUnits.h b/NPLib/Core/NPSystemOfUnits.h index 11feef095077ee3418546397fee2a5ad41aa54c0..66380ee427431b753392ab775087b78e7a5deb0e 100644 --- a/NPLib/Core/NPSystemOfUnits.h +++ b/NPLib/Core/NPSystemOfUnits.h @@ -168,9 +168,8 @@ namespace NPUNITS { // //#define pascal hep_pascal // a trick to avoid warnings static const double hep_pascal = newton/m2; // pascal = 6.24150 e+3 * MeV/mm3 - static const double pascal = newton/m2; // pascal = 6.24150 e+3 * MeV/mm3 - static const double bar = 100000*pascal; // bar = 6.24150 e+8 * MeV/mm3 - static const double atmosphere = 101325*pascal; // atm = 6.32420 e+8 * MeV/mm3 + static const double bar = 100000*hep_pascal; // bar = 6.24150 e+8 * MeV/mm3 + static const double atmosphere = 101325*hep_pascal; // atm = 6.32420 e+8 * MeV/mm3 static const double torr = 0.00133322*bar; // diff --git a/NPLib/Detectors/Catana/CMakeLists.txt b/NPLib/Detectors/Catana/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..a036990ec04e4838f83d40f17553246d0fce780b --- /dev/null +++ b/NPLib/Detectors/Catana/CMakeLists.txt @@ -0,0 +1,6 @@ +add_custom_command(OUTPUT TCatanaPhysicsDict.cxx COMMAND ../../scripts/build_dict.sh TCatanaPhysics.h TCatanaPhysicsDict.cxx TCatanaPhysics.rootmap libNPCatana.dylib DEPENDS TCatanaPhysics.h) +add_custom_command(OUTPUT TCatanaDataDict.cxx COMMAND ../../scripts/build_dict.sh TCatanaData.h TCatanaDataDict.cxx TCatanaData.rootmap libNPCatana.dylib DEPENDS TCatanaData.h) +add_library(NPCatana SHARED TCatanaSpectra.cxx TCatanaData.cxx TCatanaPhysics.cxx TCatanaDataDict.cxx TCatanaPhysicsDict.cxx ) +target_link_libraries(NPCatana ${ROOT_LIBRARIES} NPCore) +install(FILES TCatanaData.h TCatanaPhysics.h TCatanaSpectra.h DESTINATION ${CMAKE_INCLUDE_OUTPUT_DIRECTORY}) + diff --git a/NPLib/Detectors/Catana/TCatanaData.cxx b/NPLib/Detectors/Catana/TCatanaData.cxx new file mode 100644 index 0000000000000000000000000000000000000000..8206f21115082dab1d15aae6a36a90652f3e2c4c --- /dev/null +++ b/NPLib/Detectors/Catana/TCatanaData.cxx @@ -0,0 +1,79 @@ +/***************************************************************************** + * Copyright (C) 2009-2020 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 : July 2020 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class hold Catana Raw data * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + * * + *****************************************************************************/ +#include "TCatanaData.h" + +#include <iostream> +#include <fstream> +#include <sstream> +#include <string> +using namespace std; + +ClassImp(TCatanaData) + + +////////////////////////////////////////////////////////////////////// +TCatanaData::TCatanaData() { +} + + + +////////////////////////////////////////////////////////////////////// +TCatanaData::~TCatanaData() { +} + + + +////////////////////////////////////////////////////////////////////// +void TCatanaData::Clear() { + // Energy + fCatana_E_DetectorNbr.clear(); + fCatana_Energy.clear(); + // Time + fCatana_T_DetectorNbr.clear(); + fCatana_Time.clear(); +} + + + +////////////////////////////////////////////////////////////////////// +void TCatanaData::Dump() const { + // This method is very useful for debuging and worth the dev. + cout << "XXXXXXXXXXXXXXXXXXXXXXXX New Event [TCatanaData::Dump()] XXXXXXXXXXXXXXXXX" << endl; + + // Energy + size_t mysize = fCatana_E_DetectorNbr.size(); + cout << "Catana_E_Mult: " << mysize << endl; + + for (size_t i = 0 ; i < mysize ; i++){ + cout << "DetNbr: " << fCatana_E_DetectorNbr[i] + << " Energy: " << fCatana_Energy[i]; + } + + // Time + mysize = fCatana_T_DetectorNbr.size(); + cout << "Catana_T_Mult: " << mysize << endl; + + for (size_t i = 0 ; i < mysize ; i++){ + cout << "DetNbr: " << fCatana_T_DetectorNbr[i] + << " Time: " << fCatana_Time[i]; + } +} diff --git a/NPLib/Detectors/Catana/TCatanaData.h b/NPLib/Detectors/Catana/TCatanaData.h new file mode 100644 index 0000000000000000000000000000000000000000..529a320ea70a661f845270e1c42c61ced6c52686 --- /dev/null +++ b/NPLib/Detectors/Catana/TCatanaData.h @@ -0,0 +1,104 @@ +#ifndef __CatanaDATA__ +#define __CatanaDATA__ +/***************************************************************************** + * Copyright (C) 2009-2020 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 : July 2020 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class hold Catana Raw data * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + * * + *****************************************************************************/ + +// STL +#include <vector> +using namespace std; + +// ROOT +#include "TObject.h" + +class TCatanaData : public TObject { + ////////////////////////////////////////////////////////////// + // data members are hold into vectors in order + // to allow multiplicity treatment + private: + // Energy + vector<UShort_t> fCatana_E_DetectorNbr; + vector<Double_t> fCatana_Energy; + + // Time + vector<UShort_t> fCatana_T_DetectorNbr; + vector<Double_t> fCatana_Time; + + + ////////////////////////////////////////////////////////////// + // Constructor and destructor + public: + TCatanaData(); + ~TCatanaData(); + + + ////////////////////////////////////////////////////////////// + // 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){ + fCatana_E_DetectorNbr.push_back(DetNbr); + fCatana_Energy.push_back(Energy); + };//! + + // Time + inline void SetTime(const UShort_t& DetNbr,const Double_t& Time) { + fCatana_T_DetectorNbr.push_back(DetNbr); + fCatana_Time.push_back(Time); + };//! + + + ////////////////////// GETTERS //////////////////////// + // Energy + inline UShort_t GetMultEnergy() const + {return fCatana_E_DetectorNbr.size();} + inline UShort_t GetE_DetectorNbr(const unsigned int &i) const + {return fCatana_E_DetectorNbr[i];}//! + inline Double_t Get_Energy(const unsigned int &i) const + {return fCatana_Energy[i];}//! + + // Time + inline UShort_t GetMultTime() const + {return fCatana_T_DetectorNbr.size();} + inline UShort_t GetT_DetectorNbr(const unsigned int &i) const + {return fCatana_T_DetectorNbr[i];}//! + inline Double_t Get_Time(const unsigned int &i) const + {return fCatana_Time[i];}//! + + + ////////////////////////////////////////////////////////////// + // Required for ROOT dictionnary + ClassDef(TCatanaData,1) // CatanaData structure +}; + +#endif diff --git a/NPLib/Detectors/Catana/TCatanaPhysics.cxx b/NPLib/Detectors/Catana/TCatanaPhysics.cxx new file mode 100644 index 0000000000000000000000000000000000000000..f3618f7ee564cf9e3d8101ade2011e28962c3446 --- /dev/null +++ b/NPLib/Detectors/Catana/TCatanaPhysics.cxx @@ -0,0 +1,407 @@ +/***************************************************************************** + * Copyright (C) 2009-2020 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 : July 2020 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class hold Catana Treated data * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + * * + *****************************************************************************/ + +#include "TCatanaPhysics.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" +#include "NPSystemOfUnits.h" +using namespace NPUNITS; +#include "NPTrackingUtility.h" + +// ROOT +#include "TChain.h" + +ClassImp(TCatanaPhysics) + + +/////////////////////////////////////////////////////////////////////////// +TCatanaPhysics::TCatanaPhysics() + : m_EventData(new TCatanaData), + m_PreTreatedData(new TCatanaData), + m_EventPhysics(this), + m_Spectra(0), + m_E_RAW_Threshold(0), // adc channels + m_E_Threshold(0), // MeV + m_NumberOfDetectors(0) { + } + + +/////////////////////////////////////////////////////////////////////////// +void TCatanaPhysics::AddDetector(double X, double Y, double Z, double Theta, double Phi, int ID, int Type){ + m_NumberOfDetectors++; + TVector3 Pos(X,Y,Z); + m_Position[ID]=Pos+m_Ref; + m_Theta[ID]=Theta; + m_Phi[ID]=Phi; + m_Type[ID]=Type; +} + +/////////////////////////////////////////////////////////////////////////// +void TCatanaPhysics::BuildSimplePhysicalEvent() { + BuildPhysicalEvent(); +} + + +/////////////////////////////////////////////////////////////////////////// +TVector3 TCatanaPhysics::GetPositionOfInteraction(int& i){ + return m_Position[DetectorNumber[i]]; +} +/////////////////////////////////////////////////////////////////////////// +void TCatanaPhysics::ReadCSV(string path){ + std::ifstream csv(path); + if(!csv.is_open()){ + std::ostringstream message; + message << "Catana csv file " << path << " not found " << std::endl; + } + + int ID, type,layer; + double X,Y,Z,Theta,Phi; + string buffer; + // ignore first line + getline(csv,buffer); + while(csv >> ID >> buffer >> type >> buffer >> layer >> buffer >> X >> buffer >> Y >> buffer >> Z >> buffer >> Theta >> buffer >> Phi){ + if(type<6) + AddDetector(X,Y,Z,Theta*deg,Phi*deg,ID,type); + else{ + // ignore other type for which I don't have the geometry + } + } + + return; +} +/////////////////////////////////////////////////////////////////////////// +void TCatanaPhysics::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)); + } + } + } +} + +/////////////////////////////////////////////////////////////////////////// +unsigned int TCatanaPhysics::FindClosestHitToLine(const TVector3& v1, const TVector3& v2,double& d){ + + d = 1e32; + unsigned result = 0; + unsigned int size = DetectorNumber.size(); + for(unsigned int i = 0 ; i < size ; i++){ + double current_d = NPL::MinimumDistancePointLine(v1,v2,m_Position[DetectorNumber[i]]) ; + if(current_d < d){ + d=current_d; + result=i; + } + } + + if(d==1e32) + d=-1000; + + return result; +} +/////////////////////////////////////////////////////////////////////////// +void TCatanaPhysics::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("Catana/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("Catana/TIME"+NPL::itoa(m_EventData->GetT_DetectorNbr(i)),m_EventData->Get_Time(i)); + m_PreTreatedData->SetTime(m_EventData->GetT_DetectorNbr(i), Time); + } +} + + + +/////////////////////////////////////////////////////////////////////////// +void TCatanaPhysics::ReadAnalysisConfig() { + bool ReadingStatus = false; + + // path to file + string FileName = "./configs/ConfigCatana.dat"; + + // open analysis config file + ifstream AnalysisConfigFile; + AnalysisConfigFile.open(FileName.c_str()); + + if (!AnalysisConfigFile.is_open()) { + cout << " No ConfigCatana.dat found: Default parameter loaded for Analayis " << FileName << endl; + return; + } + cout << " Loading user parameter for Analysis from ConfigCatana.dat " << endl; + + // Save it in a TAsciiFile + TAsciiFile* asciiConfig = RootOutput::getInstance()->GetAsciiFileAnalysisConfig(); + asciiConfig->AppendLine("%%% ConfigCatana.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 = "ConfigCatana"; + 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 TCatanaPhysics::Clear() { + DetectorNumber.clear(); + Energy.clear(); + Time.clear(); +} + + + +/////////////////////////////////////////////////////////////////////////// +void TCatanaPhysics::ReadConfiguration(NPL::InputParser parser){ + // CSV config + vector<NPL::InputBlock*> blocks = parser.GetAllBlocksWithTokenAndValue("Catana","CSV"); + if(NPOptionManager::getInstance()->GetVerboseLevel()) + cout << "//// " << blocks.size() << " CSV block found " << endl; + + vector<string> token = {"Path","Pos","Rshift"}; + + for(unsigned int i = 0 ; i < blocks.size() ; i++){ + if(blocks[i]->HasTokenList(token)){ + if(NPOptionManager::getInstance()->GetVerboseLevel()) + cout << endl << "//// Catana " << i+1 << endl; + string path = blocks[i]->GetString("Path"); + //double Rshift = blocks[i]->GetDouble("Rshift","micrometer"); + // Reference position of the whole array + m_Ref = blocks[i]->GetTVector3("Pos","mm"); + ReadCSV(path); + } + else{ + cout << "ERROR: check your input file formatting " << endl; + exit(1); + } + } + + // Type 1 + blocks = parser.GetAllBlocksWithTokenAndValue("Catana","Detector"); + if(NPOptionManager::getInstance()->GetVerboseLevel()) + cout << "//// " << blocks.size() << " detectors found " << endl; + + token = {"X","Y","Z","Theta","Phi","ID","Type"}; + + for(unsigned int i = 0 ; i < blocks.size() ; i++){ + if(blocks[i]->HasTokenList(token)){ + if(NPOptionManager::getInstance()->GetVerboseLevel()) + cout << endl << "//// Catana " << i+1 << endl; + double X = blocks[i]->GetDouble("X","mm"); + double Y = blocks[i]->GetDouble("Y","mm"); + double Z = blocks[i]->GetDouble("Z","mm"); + double Theta = blocks[i]->GetDouble("Theta","deg"); + double Phi = blocks[i]->GetDouble("Phi","deg"); + int ID = blocks[i]->GetInt("ID"); + int Type = blocks[i]->GetInt("Type"); + AddDetector(X,Y,Z,Theta,Phi,ID,Type); + } + else{ + cout << "ERROR: check your input file formatting " << endl; + exit(1); + } + } + +} + + + +/////////////////////////////////////////////////////////////////////////// +void TCatanaPhysics::InitSpectra() { + m_Spectra = new TCatanaSpectra(m_NumberOfDetectors); +} + + + +/////////////////////////////////////////////////////////////////////////// +void TCatanaPhysics::FillSpectra() { + m_Spectra -> FillRawSpectra(m_EventData); + m_Spectra -> FillPreTreatedSpectra(m_PreTreatedData); + m_Spectra -> FillPhysicsSpectra(m_EventPhysics); +} + + + +/////////////////////////////////////////////////////////////////////////// +void TCatanaPhysics::CheckSpectra() { + m_Spectra->CheckSpectra(); +} + + + +/////////////////////////////////////////////////////////////////////////// +void TCatanaPhysics::ClearSpectra() { + // To be done +} + + + +/////////////////////////////////////////////////////////////////////////// +map< string , TH1*> TCatanaPhysics::GetSpectra() { + if(m_Spectra) + return m_Spectra->GetMapHisto(); + else{ + map< string , TH1*> empty; + return empty; + } +} + +/////////////////////////////////////////////////////////////////////////// +void TCatanaPhysics::WriteSpectra() { + m_Spectra->WriteSpectra(); +} + + + +/////////////////////////////////////////////////////////////////////////// +void TCatanaPhysics::AddParameterToCalibrationManager() { + CalibrationManager* Cal = CalibrationManager::getInstance(); + for (int i = 0; i < m_NumberOfDetectors; ++i) { + Cal->AddParameter("Catana", "D"+ NPL::itoa(i+1)+"_ENERGY","Catana_D"+ NPL::itoa(i+1)+"_ENERGY"); + Cal->AddParameter("Catana", "D"+ NPL::itoa(i+1)+"_TIME","Catana_D"+ NPL::itoa(i+1)+"_TIME"); + } +} + + + +/////////////////////////////////////////////////////////////////////////// +void TCatanaPhysics::InitializeRootInputRaw() { + TChain* inputChain = RootInput::getInstance()->GetChain(); + inputChain->SetBranchStatus("Catana", true ); + inputChain->SetBranchAddress("Catana", &m_EventData ); +} + + + +/////////////////////////////////////////////////////////////////////////// +void TCatanaPhysics::InitializeRootInputPhysics() { + TChain* inputChain = RootInput::getInstance()->GetChain(); + inputChain->SetBranchAddress("Catana", &m_EventPhysics); +} + + + +/////////////////////////////////////////////////////////////////////////// +void TCatanaPhysics::InitializeRootOutput() { + TTree* outputTree = RootOutput::getInstance()->GetTree(); + outputTree->Branch("Catana", "TCatanaPhysics", &m_EventPhysics); +} + + + +//////////////////////////////////////////////////////////////////////////////// +// Construct Method to be pass to the DetectorFactory // +//////////////////////////////////////////////////////////////////////////////// +NPL::VDetector* TCatanaPhysics::Construct() { + return (NPL::VDetector*) new TCatanaPhysics(); +} + + + +//////////////////////////////////////////////////////////////////////////////// +// Registering the construct method to the factory // +//////////////////////////////////////////////////////////////////////////////// +extern "C"{ + class proxy_Catana{ + public: + proxy_Catana(){ + NPL::DetectorFactory::getInstance()->AddToken("Catana","Catana"); + NPL::DetectorFactory::getInstance()->AddDetector("Catana",TCatanaPhysics::Construct); + } + }; + + proxy_Catana p_Catana; +} + diff --git a/NPLib/Detectors/Catana/TCatanaPhysics.h b/NPLib/Detectors/Catana/TCatanaPhysics.h new file mode 100644 index 0000000000000000000000000000000000000000..f9fc98d14c71bc3b39a9c9502031cf4d4c9742fd --- /dev/null +++ b/NPLib/Detectors/Catana/TCatanaPhysics.h @@ -0,0 +1,191 @@ +#ifndef TCatanaPHYSICS_H +#define TCatanaPHYSICS_H +/***************************************************************************** + * Copyright (C) 2009-2020 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 : July 2020 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class hold Catana 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 "TCatanaData.h" +#include "TCatanaSpectra.h" +#include "NPCalibrationManager.h" +#include "NPVDetector.h" +#include "NPInputParser.h" +// forward declaration +class TCatanaSpectra; + + + +class TCatanaPhysics : public TObject, public NPL::VDetector { + ////////////////////////////////////////////////////////////// + // constructor and destructor + public: + TCatanaPhysics(); + ~TCatanaPhysics() {}; + + + ////////////////////////////////////////////////////////////// + // 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(double X, double Y, double Z, double Theta, double Phi, int ID, int Type); + void ReadCSV(string path); + + // Position method and variable + public: + map<int,TVector3> m_Position;//! + map<int,double> m_Theta;//! + map<int,double> m_Phi;//! + map<int,int> m_Type;//! + TVector3 m_Ref;//! + TVector3 GetPositionOfInteraction(int& i);//! + // Return index of the closest hit to line defined by v1 and v2 + unsigned int FindClosestHitToLine(const TVector3& v1, const TVector3& v2, double& d); + + ////////////////////////////////////////////////////////////// + // 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 TCatanaSpectra class + // instantiate the TCatanaSpectra 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 Catana 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 TCatanaData object to TCatanaPhysics. + // needed for online analysis for example + void SetRawDataPointer(TCatanaData* rawDataPointer) {m_EventData = rawDataPointer;} + + // objects are not written in the TTree + private: + TCatanaData* m_EventData; //! + TCatanaData* m_PreTreatedData; //! + TCatanaPhysics* m_EventPhysics; //! + + // getters for raw and pre-treated data object + public: + TCatanaData* GetRawData() const {return m_EventData;} + TCatanaData* 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: + TCatanaSpectra* m_Spectra; // ! + + // spectra getter + public: + map<string, TH1*> GetSpectra(); + + // Static constructor to be passed to the Detector Factory + public: + static NPL::VDetector* Construct(); + + ClassDef(TCatanaPhysics,1) // CatanaPhysics structure +}; +#endif diff --git a/NPLib/Detectors/Catana/TCatanaSpectra.cxx b/NPLib/Detectors/Catana/TCatanaSpectra.cxx new file mode 100644 index 0000000000000000000000000000000000000000..18f211978aa43b2d493643668252d0f783a3b6db --- /dev/null +++ b/NPLib/Detectors/Catana/TCatanaSpectra.cxx @@ -0,0 +1,174 @@ +/***************************************************************************** + * Copyright (C) 2009-2020 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 : July 2020 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class hold Catana Spectra * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + * * + *****************************************************************************/ + +// class header +#include "TCatanaSpectra.h" + +// STL +#include <iostream> +#include <string> +using namespace std; + +// NPTool header +#include "NPOptionManager.h" + + + +//////////////////////////////////////////////////////////////////////////////// +TCatanaSpectra::TCatanaSpectra() + : fNumberOfDetectors(0) { + SetName("Catana"); +} + + + +//////////////////////////////////////////////////////////////////////////////// +TCatanaSpectra::TCatanaSpectra(unsigned int NumberOfDetectors) { + if(NPOptionManager::getInstance()->GetVerboseLevel()>0) + cout << "************************************************" << endl + << "TCatanaSpectra : Initalizing control spectra for " + << NumberOfDetectors << " Detectors" << endl + << "************************************************" << endl ; + SetName("Catana"); + fNumberOfDetectors = NumberOfDetectors; + + InitRawSpectra(); + InitPreTreatedSpectra(); + InitPhysicsSpectra(); +} + + + +//////////////////////////////////////////////////////////////////////////////// +TCatanaSpectra::~TCatanaSpectra() { +} + + + +//////////////////////////////////////////////////////////////////////////////// +void TCatanaSpectra::InitRawSpectra() { + static string name; + for (unsigned int i = 0; i < fNumberOfDetectors; i++) { // loop on number of detectors + // Energy + name = "Catana"+NPL::itoa(i+1)+"_ENERGY_RAW"; + AddHisto1D(name, name, 4096, 0, 16384, "Catana/RAW"); + // Time + name = "Catana"+NPL::itoa(i+1)+"_TIME_RAW"; + AddHisto1D(name, name, 4096, 0, 16384, "Catana/RAW"); + } // end loop on number of detectors +} + + + +//////////////////////////////////////////////////////////////////////////////// +void TCatanaSpectra::InitPreTreatedSpectra() { + static string name; + for (unsigned int i = 0; i < fNumberOfDetectors; i++) { // loop on number of detectors + // Energy + name = "Catana"+NPL::itoa(i+1)+"_ENERGY_CAL"; + AddHisto1D(name, name, 500, 0, 25, "Catana/CAL"); + // Time + name = "Catana"+NPL::itoa(i+1)+"_TIME_CAL"; + AddHisto1D(name, name, 500, 0, 25, "Catana/CAL"); + + + } // end loop on number of detectors +} + + + +//////////////////////////////////////////////////////////////////////////////// +void TCatanaSpectra::InitPhysicsSpectra() { + static string name; + // Kinematic Plot + name = "Catana_ENERGY_TIME"; + AddHisto2D(name, name, 500, 0, 500, 500, 0, 50, "Catana/PHY"); +} + + + +//////////////////////////////////////////////////////////////////////////////// +void TCatanaSpectra::FillRawSpectra(TCatanaData* RawData) { + static string name; + static string family; + + // Energy + unsigned int sizeE = RawData->GetMultEnergy(); + for (unsigned int i = 0; i < sizeE; i++) { + name = "Catana"+NPL::itoa(RawData->GetE_DetectorNbr(i))+"_ENERGY_RAW"; + family = "Catana/RAW"; + + FillSpectra(family,name,RawData->Get_Energy(i)); + } + + // Time + unsigned int sizeT = RawData->GetMultTime(); + for (unsigned int i = 0; i < sizeT; i++) { + name = "Catana"+NPL::itoa(RawData->GetT_DetectorNbr(i))+"_TIME_RAW"; + family = "Catana/RAW"; + + FillSpectra(family,name,RawData->Get_Time(i)); + } +} + + + +//////////////////////////////////////////////////////////////////////////////// +void TCatanaSpectra::FillPreTreatedSpectra(TCatanaData* PreTreatedData) { + static string name; + static string family; + + // Energy + unsigned int sizeE = PreTreatedData->GetMultEnergy(); + for (unsigned int i = 0; i < sizeE; i++) { + name = "Catana"+NPL::itoa(PreTreatedData->GetE_DetectorNbr(i))+"_ENERGY_CAL"; + family = "Catana/CAL"; + + FillSpectra(family,name,PreTreatedData->Get_Energy(i)); + } + + // Time + unsigned int sizeT = PreTreatedData->GetMultTime(); + for (unsigned int i = 0; i < sizeT; i++) { + name = "Catana"+NPL::itoa(PreTreatedData->GetT_DetectorNbr(i))+"_TIME_CAL"; + family = "Catana/CAL"; + + FillSpectra(family,name,PreTreatedData->Get_Time(i)); + } +} + + + +//////////////////////////////////////////////////////////////////////////////// +void TCatanaSpectra::FillPhysicsSpectra(TCatanaPhysics* Physics) { + static string name; + static string family; + family= "Catana/PHY"; + + // Energy vs time + unsigned int sizeE = Physics->Energy.size(); + for(unsigned int i = 0 ; i < sizeE ; i++){ + name = "Catana_ENERGY_TIME"; + FillSpectra(family,name,Physics->Energy[i],Physics->Time[i]); + } +} + diff --git a/NPLib/Detectors/Catana/TCatanaSpectra.h b/NPLib/Detectors/Catana/TCatanaSpectra.h new file mode 100644 index 0000000000000000000000000000000000000000..f81b837985ba875f945ea4f519c6129414676bfe --- /dev/null +++ b/NPLib/Detectors/Catana/TCatanaSpectra.h @@ -0,0 +1,62 @@ +#ifndef TCatanaSPECTRA_H +#define TCatanaSPECTRA_H +/***************************************************************************** + * Copyright (C) 2009-2020 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 : July 2020 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class hold Catana Spectra * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + * * + *****************************************************************************/ + +// NPLib headers +#include "NPVSpectra.h" +#include "TCatanaData.h" +#include "TCatanaPhysics.h" + +// Forward Declaration +class TCatanaPhysics; + + +class TCatanaSpectra : public VSpectra { + ////////////////////////////////////////////////////////////// + // constructor and destructor + public: + TCatanaSpectra(); + TCatanaSpectra(unsigned int NumberOfDetectors); + ~TCatanaSpectra(); + + ////////////////////////////////////////////////////////////// + // Initialization methods + private: + void InitRawSpectra(); + void InitPreTreatedSpectra(); + void InitPhysicsSpectra(); + + ////////////////////////////////////////////////////////////// + // Filling methods + public: + void FillRawSpectra(TCatanaData*); + void FillPreTreatedSpectra(TCatanaData*); + void FillPhysicsSpectra(TCatanaPhysics*); + + ////////////////////////////////////////////////////////////// + // Detector parameters + private: + unsigned int fNumberOfDetectors; +}; + +#endif diff --git a/NPLib/Detectors/MUST2/TMust2Physics.cxx b/NPLib/Detectors/MUST2/TMust2Physics.cxx index f73bde5054b3fbb441bc6c5dbe113d648eb59c3b..71cb70555d951407e9f41a3b054edb98ad7ae91e 100644 --- a/NPLib/Detectors/MUST2/TMust2Physics.cxx +++ b/NPLib/Detectors/MUST2/TMust2Physics.cxx @@ -1353,7 +1353,7 @@ double fSi_X_E(const TMust2Data* m_EventData, const int& i) { name += NPL::itoa(m_EventData->GetMMStripXEStripNbr(i)); name += "_E"; return CalibrationManager::getInstance()->ApplyCalibration( - name, m_EventData->GetMMStripXEEnergy(i)); + name, m_EventData->GetMMStripXEEnergy(i),1); } double fSi_X_T(const TMust2Data* m_EventData, const int& i) { @@ -1364,7 +1364,7 @@ double fSi_X_T(const TMust2Data* m_EventData, const int& i) { name += NPL::itoa(m_EventData->GetMMStripXTStripNbr(i)); name += "_T"; return CalibrationManager::getInstance()->ApplyCalibration( - name, m_EventData->GetMMStripXTTime(i)); + name, m_EventData->GetMMStripXTTime(i),1); } // Y @@ -1376,7 +1376,7 @@ double fSi_Y_E(const TMust2Data* m_EventData, const int& i) { name += NPL::itoa(m_EventData->GetMMStripYEStripNbr(i)); name += "_E"; return CalibrationManager::getInstance()->ApplyCalibration( - name, m_EventData->GetMMStripYEEnergy(i)); + name, m_EventData->GetMMStripYEEnergy(i),1); } double fSi_Y_T(const TMust2Data* m_EventData, const int& i) { @@ -1387,7 +1387,7 @@ double fSi_Y_T(const TMust2Data* m_EventData, const int& i) { name += NPL::itoa(m_EventData->GetMMStripYTStripNbr(i)); name += "_T"; return CalibrationManager::getInstance()->ApplyCalibration( - name, m_EventData->GetMMStripYTTime(i)); + name, m_EventData->GetMMStripYTTime(i),1); } // SiLi @@ -1400,7 +1400,7 @@ double fSiLi_E(const TMust2Data* m_EventData, const int& i) { name += "_E"; return CalibrationManager::getInstance()->ApplyCalibration( - name, m_EventData->GetMMSiLiEEnergy(i)); + name, m_EventData->GetMMSiLiEEnergy(i),1); } double fSiLi_T(const TMust2Data* m_EventData, const int& i) { @@ -1411,7 +1411,7 @@ double fSiLi_T(const TMust2Data* m_EventData, const int& i) { name += NPL::itoa(m_EventData->GetMMSiLiTPadNbr(i)); name += "_T"; return CalibrationManager::getInstance()->ApplyCalibration( - name, m_EventData->GetMMSiLiTTime(i)); + name, m_EventData->GetMMSiLiTTime(i),1); } // CsI @@ -1423,7 +1423,7 @@ double fCsI_E(const TMust2Data* m_EventData, const int& i) { name += NPL::itoa(m_EventData->GetMMCsIECristalNbr(i)); name += "_E"; return CalibrationManager::getInstance()->ApplyCalibration( - name, m_EventData->GetMMCsIEEnergy(i)); + name, m_EventData->GetMMCsIEEnergy(i),1); } double fCsI_T(const TMust2Data* m_EventData, const int& i) { @@ -1434,7 +1434,7 @@ double fCsI_T(const TMust2Data* m_EventData, const int& i) { name += NPL::itoa(m_EventData->GetMMCsITCristalNbr(i)); name += "_T"; return CalibrationManager::getInstance()->ApplyCalibration( - name, m_EventData->GetMMCsITTime(i)); + name, m_EventData->GetMMCsITTime(i),1); } } // namespace MUST2_LOCAL diff --git a/NPLib/Detectors/Mugast/TMugastPhysics.cxx b/NPLib/Detectors/Mugast/TMugastPhysics.cxx index fb0690af68fc9b38ffad16bbee9474b0d687d7cd..c6d27e01c14bf2729b921c628dfa632dff235867 100644 --- a/NPLib/Detectors/Mugast/TMugastPhysics.cxx +++ b/NPLib/Detectors/Mugast/TMugastPhysics.cxx @@ -997,7 +997,8 @@ void TMugastPhysics::AddTelescope(MG_DetectorType type,double theta, double phi, m_StripPositionZ.push_back(OneTelescopeStripPositionZ); } -TVector3 TMugastPhysics::GetPositionOfInteraction(const int i) { +/////////////////////////////////////////////////////////////////////////////// +TVector3 TMugastPhysics::GetPositionOfInteraction(const int i,bool random) { TVector3 Position = TVector3(GetStripPositionX(TelescopeNumber[i], DSSD_X[i], DSSD_Y[i]), GetStripPositionY(TelescopeNumber[i], DSSD_X[i], DSSD_Y[i]), @@ -1006,6 +1007,7 @@ TVector3 TMugastPhysics::GetPositionOfInteraction(const int i) { return Position; } +/////////////////////////////////////////////////////////////////////////////// TVector3 TMugastPhysics::GetTelescopeNormal(const int i) { TVector3 U = TVector3(GetStripPositionX(TelescopeNumber[i], 128, 1), GetStripPositionY(TelescopeNumber[i], 128, 1), @@ -1040,7 +1042,7 @@ namespace MUGAST_LOCAL { name += NPL::itoa(m_EventData->GetDSSDXEStripNbr(i)); name += "_E"; return CalibrationManager::getInstance()->ApplyCalibration( - name, m_EventData->GetDSSDXEEnergy(i)); + name, m_EventData->GetDSSDXEEnergy(i),1); } double fDSSD_X_T(const TMugastData* m_EventData, const int& i) { @@ -1051,7 +1053,7 @@ namespace MUGAST_LOCAL { name += NPL::itoa(m_EventData->GetDSSDXTStripNbr(i)); name += "_T"; return CalibrationManager::getInstance()->ApplyCalibration( - name, m_EventData->GetDSSDXTTime(i)); + name, m_EventData->GetDSSDXTTime(i),1); } // Y @@ -1063,7 +1065,7 @@ namespace MUGAST_LOCAL { name += NPL::itoa(m_EventData->GetDSSDYEStripNbr(i)); name += "_E"; return CalibrationManager::getInstance()->ApplyCalibration( - name, m_EventData->GetDSSDYEEnergy(i)); + name, m_EventData->GetDSSDYEEnergy(i),1); } double fDSSD_Y_T(const TMugastData* m_EventData, const int& i) { @@ -1074,7 +1076,7 @@ namespace MUGAST_LOCAL { name += NPL::itoa(m_EventData->GetDSSDYTStripNbr(i)); name += "_T"; return CalibrationManager::getInstance()->ApplyCalibration( - name, m_EventData->GetDSSDYTTime(i)); + name, m_EventData->GetDSSDYTTime(i),1); } // SecondLayer @@ -1086,7 +1088,7 @@ namespace MUGAST_LOCAL { name += NPL::itoa(m_EventData->GetSecondLayerEStripNbr(i)); name += "_E"; return CalibrationManager::getInstance()->ApplyCalibration( - name, m_EventData->GetSecondLayerEEnergy(i)); + name, m_EventData->GetSecondLayerEEnergy(i),1); } double fSecondLayer_T(const TMugastData* m_EventData, const int& i) { @@ -1097,7 +1099,7 @@ namespace MUGAST_LOCAL { name += NPL::itoa(m_EventData->GetSecondLayerTStripNbr(i)); name += "_T"; return CalibrationManager::getInstance()->ApplyCalibration( - name, m_EventData->GetSecondLayerTTime(i)); + name, m_EventData->GetSecondLayerTTime(i),1); } } diff --git a/NPLib/Detectors/Mugast/TMugastPhysics.h b/NPLib/Detectors/Mugast/TMugastPhysics.h index a93f38af9d4b75736cb9bea21608f6b1b5d18ac2..38b7f8e6d8d09389c4149cf95efc7f439c934e82 100644 --- a/NPLib/Detectors/Mugast/TMugastPhysics.h +++ b/NPLib/Detectors/Mugast/TMugastPhysics.h @@ -204,7 +204,7 @@ class TMugastPhysics : public TObject, public NPL::VDetector { double GetEnergyDeposit(const int i) const { return TotalEnergy[i]; }; - TVector3 GetPositionOfInteraction(const int i) ; + TVector3 GetPositionOfInteraction(const int i,bool random=false) ; TVector3 GetTelescopeNormal(const int i) ; private: // Parameter used in the analysis diff --git a/NPLib/Detectors/Strasse/CMakeLists.txt b/NPLib/Detectors/Strasse/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..d4d73e01ca6fccf6aab5c75457ebba4a8b82e2e5 --- /dev/null +++ b/NPLib/Detectors/Strasse/CMakeLists.txt @@ -0,0 +1,6 @@ +add_custom_command(OUTPUT TStrassePhysicsDict.cxx COMMAND ../../scripts/build_dict.sh TStrassePhysics.h TStrassePhysicsDict.cxx TStrassePhysics.rootmap libNPStrasse.dylib DEPENDS TStrassePhysics.h) +add_custom_command(OUTPUT TStrasseDataDict.cxx COMMAND ../../scripts/build_dict.sh TStrasseData.h TStrasseDataDict.cxx TStrasseData.rootmap libNPStrasse.dylib DEPENDS TStrasseData.h) +add_library(NPStrasse SHARED TStrasseSpectra.cxx TStrasseData.cxx TStrassePhysics.cxx TStrasseDataDict.cxx TStrassePhysicsDict.cxx ) +target_link_libraries(NPStrasse ${ROOT_LIBRARIES} NPCore) +install(FILES TStrasseData.h TStrassePhysics.h TStrasseSpectra.h DESTINATION ${CMAKE_INCLUDE_OUTPUT_DIRECTORY}) + diff --git a/NPLib/Detectors/Strasse/TStrasseData.cxx b/NPLib/Detectors/Strasse/TStrasseData.cxx new file mode 100644 index 0000000000000000000000000000000000000000..638d1d58daf602f669365cbaaaff00cfa1663657 --- /dev/null +++ b/NPLib/Detectors/Strasse/TStrasseData.cxx @@ -0,0 +1,83 @@ +/***************************************************************************** + * Copyright (C) 2009-2020 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: F. Flavigny contact : flavigny@lpccaen.in2p3.fr * + * * + * Creation Date : July 2020 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class hold Strasse Raw data * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + * * + *****************************************************************************/ +#include "TStrasseData.h" + +#include <iostream> +#include <fstream> +#include <sstream> +#include <string> +using namespace std; + +ClassImp(TStrasseData) + + +////////////////////////////////////////////////////////////////////// +TStrasseData::TStrasseData() { +} + + + +////////////////////////////////////////////////////////////////////// +TStrasseData::~TStrasseData() { +} + + + +////////////////////////////////////////////////////////////////////// +void TStrasseData::Clear() { + // Energy X + fInner_TE_DetectorNbr.clear(); + fInner_TE_StripNbr.clear(); + fInner_TE_Energy.clear(); + // Energy L + fInner_LE_DetectorNbr.clear(); + fInner_LE_StripNbr.clear(); + fInner_LE_Energy.clear(); + + // Energy X + fOuter_TE_DetectorNbr.clear(); + fOuter_TE_StripNbr.clear(); + fOuter_TE_Energy.clear(); + // Energy L + fOuter_LE_DetectorNbr.clear(); + fOuter_LE_StripNbr.clear(); + fOuter_LE_Energy.clear(); + +} + + + +////////////////////////////////////////////////////////////////////// +void TStrasseData::Dump() const { + // This method is very useful for debuging and worth the dev. + cout << "XXXXXXXXXXXXXXXXXXXXXXXX New Event [TStrasseData::Dump()] XXXXXXXXXXXXXXXXX" << endl; + + // Energy + size_t mysize = fInner_TE_DetectorNbr.size(); + cout << "Inner Strasse_TE_Mult: " << mysize << endl; + + for (size_t i = 0 ; i < mysize ; i++){ + cout << "T-DetNbr: " << fInner_TE_DetectorNbr[i] + << " T-Energy: " << fInner_TE_Energy[i]; + } + +} diff --git a/NPLib/Detectors/Strasse/TStrasseData.h b/NPLib/Detectors/Strasse/TStrasseData.h new file mode 100644 index 0000000000000000000000000000000000000000..7b1783962bec4919e4fd506be5b5295903bf78b6 --- /dev/null +++ b/NPLib/Detectors/Strasse/TStrasseData.h @@ -0,0 +1,150 @@ +#ifndef __StrasseDATA__ +#define __StrasseDATA__ +/***************************************************************************** + * Copyright (C) 2009-2020 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: F. Flavigny contact : flavigny@lpccaen.in2p3.fr * + * * + * Creation Date : July 2020 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class hold Strasse Raw data * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + * * + *****************************************************************************/ + +// STL +#include <vector> +using namespace std; + +// ROOT +#include "TObject.h" + +class TStrasseData : public TObject { + ////////////////////////////////////////////////////////////// + // data members are hold into vectors in order + // to allow multiplicity treatment + private: + // First Stage Front Energy + vector<unsigned short> fInner_TE_DetectorNbr; + vector<unsigned short> fInner_TE_StripNbr; + vector<double> fInner_TE_Energy; + // First Stage Back Energy + vector<unsigned short> fInner_LE_DetectorNbr; + vector<unsigned short> fInner_LE_StripNbr; + vector<double> fInner_LE_Energy; + + // Second Stage Front Energy + vector<unsigned short> fOuter_TE_DetectorNbr; + vector<unsigned short> fOuter_TE_StripNbr; + vector<double> fOuter_TE_Energy; + // Second Stage Back Energy + vector<unsigned short> fOuter_LE_DetectorNbr; + vector<unsigned short> fOuter_LE_StripNbr; + vector<double> fOuter_LE_Energy; + + + ////////////////////////////////////////////////////////////// + // Constructor and destructor + public: + TStrasseData(); + ~TStrasseData(); + + + ////////////////////////////////////////////////////////////// + // 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 //////////////////////// + // First Stage Energy Front + inline void SetInnerTE(const unsigned short& DetNbr, const unsigned short& StripNbr, const Double_t& Energy){ + fInner_TE_DetectorNbr.push_back(DetNbr); + fInner_TE_StripNbr.push_back(StripNbr); + fInner_TE_Energy.push_back(Energy); + };//! + // First Stage Energy Back + inline void SetInnerLE(const unsigned short& DetNbr, const unsigned short& StripNbr, const Double_t& Energy){ + fInner_LE_DetectorNbr.push_back(DetNbr); + fInner_LE_StripNbr.push_back(StripNbr); + fInner_LE_Energy.push_back(Energy); + };//! + + ////// + // Second Stage Energy Front + inline void SetOuterTE(const unsigned short& DetNbr, const unsigned short& StripNbr, const Double_t& Energy){ + fOuter_TE_DetectorNbr.push_back(DetNbr); + fOuter_TE_StripNbr.push_back(StripNbr); + fOuter_TE_Energy.push_back(Energy); + };//! + // Second Stage Energy Back + inline void SetOuterLE(const unsigned short& DetNbr, const unsigned short& StripNbr, const Double_t& Energy){ + fOuter_LE_DetectorNbr.push_back(DetNbr); + fOuter_LE_StripNbr.push_back(StripNbr); + fOuter_LE_Energy.push_back(Energy); + };//! + + ////////////////////// GETTERS //////////////////////// + // First Stage Energy T + inline unsigned short GetInnerMultTEnergy() const + {return fInner_TE_DetectorNbr.size();} + inline unsigned short GetInner_TE_DetectorNbr(const unsigned int &i) const + {return fInner_TE_DetectorNbr[i];}//! + inline unsigned short GetInner_TE_StripNbr(const unsigned int &i) const + {return fInner_TE_StripNbr[i];}//! + inline Double_t GetInner_TE_Energy(const unsigned int &i) const + {return fInner_TE_Energy[i];}//! + // First Stage Energy L + inline unsigned short GetInnerMultLEnergy() const + {return fInner_LE_DetectorNbr.size();} + inline unsigned short GetInner_LE_DetectorNbr(const unsigned int &i) const + {return fInner_LE_DetectorNbr[i];}//! + inline unsigned short GetInner_LE_StripNbr(const unsigned int &i) const + {return fInner_LE_StripNbr[i];}//! + inline Double_t GetInner_LE_Energy(const unsigned int &i) const + {return fInner_LE_Energy[i];}//! + + ////// + // Second Stage Energy T + inline unsigned short GetOuterMultTEnergy() const + {return fOuter_TE_DetectorNbr.size();} + inline unsigned short GetOuter_TE_DetectorNbr(const unsigned int &i) const + {return fOuter_TE_DetectorNbr[i];}//! + inline unsigned short GetOuter_TE_StripNbr(const unsigned int &i) const + {return fOuter_TE_StripNbr[i];}//! + inline Double_t GetOuter_TE_Energy(const unsigned int &i) const + {return fOuter_TE_Energy[i];}//! + // Second Stage Energy L + inline unsigned short GetOuterMultLEnergy() const + {return fOuter_LE_DetectorNbr.size();} + inline unsigned short GetOuter_LE_DetectorNbr(const unsigned int &i) const + {return fOuter_LE_DetectorNbr[i];}//! + inline unsigned short GetOuter_LE_StripNbr(const unsigned int &i) const + {return fOuter_LE_StripNbr[i];}//! + inline Double_t GetOuter_LE_Energy(const unsigned int &i) const + {return fOuter_LE_Energy[i];}//! + + ////////////////////////////////////////////////////////////// + // Required for ROOT dictionnary + ClassDef(TStrasseData,1) // StrasseData structure +}; + +#endif diff --git a/NPLib/Detectors/Strasse/TStrassePhysics.cxx b/NPLib/Detectors/Strasse/TStrassePhysics.cxx new file mode 100644 index 0000000000000000000000000000000000000000..4f5d7d0110c9a78cd92fcae2c52df025a7996bfe --- /dev/null +++ b/NPLib/Detectors/Strasse/TStrassePhysics.cxx @@ -0,0 +1,885 @@ +/***************************************************************************** + * Copyright (C) 2009-2020 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: F. Flavigny contact : flavigny@lpccaen.in2p3.fr * + * * + * Creation Date : July 2020 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class hold Strasse Treated data * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + * * + *****************************************************************************/ + +#include "TStrassePhysics.h" + +// STL +#include <sstream> +#include <iostream> +#include <cmath> +#include <stdlib.h> +#include <limits> +using namespace std; + +// NPL +#include "RootInput.h" +#include "RootOutput.h" +#include "Math/Transform3D.h" +#include "Math/RotationZYX.h" +#include "NPDetectorFactory.h" +#include "NPOptionManager.h" +#include "NPSystemOfUnits.h" +using namespace NPUNITS; +// ROOT +#include "TChain.h" + +ClassImp(TStrassePhysics) + /////////////////////////////////////////////////////////////////////////// + TStrassePhysics::TStrassePhysics(){ + EventMultiplicity = 0; + m_EventData = new TStrasseData; + m_PreTreatedData = new TStrasseData; + m_EventPhysics = this; + m_Spectra = NULL; + m_E_RAW_Threshold = 0; // adc channels + m_E_Threshold = 0; // MeV + m_NumberOfInnerDetectors = 0; + m_NumberOfOuterDetectors = 0; + m_MaximumStripMultiplicityAllowed = 10; + m_StripEnergyMatching = 1.00; + + //////////////////// + // Inner Detector // + //////////////////// + // Wafer parameter + Inner_Wafer_Length=100*mm; + Inner_Wafer_Width=50*mm; + Inner_Wafer_Thickness=300*micrometer; + Inner_Wafer_AlThickness=0.4*micrometer; + Inner_Wafer_PADExternal=1*cm; + Inner_Wafer_PADInternal=1*mm; + Inner_Wafer_GuardRing=0.5*mm; + + // PCB parameter + Inner_PCB_PortWidth=1*cm; + Inner_PCB_StarboardWidth=2*mm; + Inner_PCB_BevelAngle= 60*deg; + Inner_PCB_UpstreamWidth=1*cm; + Inner_PCB_DownstreamWidth=2*mm; + Inner_PCB_MidWidth=2*mm; + Inner_PCB_Thickness=3*mm; + Inner_Wafer_TransverseStrips= 128; + Inner_Wafer_LongitudinalStrips= 128; + + //////////////////// + // Outer Detector // + //////////////////// + // Wafer parameter + Outer_Wafer_Length=150*mm; + Outer_Wafer_Width=75*mm; + Outer_Wafer_Thickness=300*micrometer; + Outer_Wafer_AlThickness=0.4*micrometer; + Outer_Wafer_PADExternal=1*cm; + Outer_Wafer_PADInternal=1*mm; + Outer_Wafer_GuardRing=0.5*mm; + + // PCB parameter + Outer_PCB_PortWidth=1*cm; + Outer_PCB_StarboardWidth=2*mm; + Outer_PCB_BevelAngle= 60*deg; + Outer_PCB_UpstreamWidth=1*cm; + Outer_PCB_DownstreamWidth=2*mm; + Outer_PCB_MidWidth=2*mm; + Outer_PCB_Thickness=3*mm; + Outer_Wafer_TransverseStrips= 128; + Outer_Wafer_LongitudinalStrips= 128; + + + } + +/////////////////////////////////////////////////////////////////////////// +void TStrassePhysics::AddInnerDetector(double R, double Z, double Phi, double Shift, TVector3 Ref){ + m_NumberOfInnerDetectors++; + double ActiveWidth = Inner_Wafer_Width-2.*Inner_Wafer_GuardRing; + double ActiveLength = Inner_Wafer_Length-Inner_Wafer_PADExternal-Inner_Wafer_PADInternal-2*Inner_Wafer_GuardRing; + double LongitudinalPitch = ActiveWidth/Inner_Wafer_LongitudinalStrips; + double TransversePitch = ActiveLength/Inner_Wafer_TransverseStrips; +//cout << ActiveWidth << " " << ActiveLength << " " << LongitudinalPitch << " " << TransversePitch << endl; + + // Vector C position of detector face center + TVector3 C(Shift,R,Z);// center of the whole detector, including PCB + C.RotateZ(-Phi); + + // Vector W normal to detector face (pointing to the back) + TVector3 W(0,1,0); + W.RotateZ(-Phi); + + // Vector U on detector face (parallel to Z axis/longitudinal strips) + TVector3 U = TVector3(0,0,1); + // Vector V on detector face (parallel to transverse strips) + TVector3 V = W.Cross(U); + + // Adding position for downstream silicon: + // Moving to corner of the silicon + TVector3 P_1_1 = C + +U*0.5*(Inner_PCB_UpstreamWidth-Inner_PCB_DownstreamWidth) // In between wafer + -U*0.5*Inner_PCB_MidWidth // Internal wafer edge + -U*Inner_Wafer_Length // External wafer edge + +U*(Inner_Wafer_GuardRing+Inner_Wafer_PADExternal) // External active wafer edge + +U*0.5*TransversePitch // middle of strip + -V*0.5*(Inner_PCB_StarboardWidth-Inner_PCB_PortWidth) + -V*0.5*Inner_Wafer_Width + +V*Inner_Wafer_GuardRing + +V*0.5*LongitudinalPitch; // middle of strip + + vector<double> lineX; + vector<double> lineY; + vector<double> lineZ; + + vector<vector<double>> OneDetectorStripPositionX; + vector<vector<double>> OneDetectorStripPositionY; + vector<vector<double>> OneDetectorStripPositionZ; + + TVector3 P; + for(int i=0; i<Inner_Wafer_TransverseStrips; i++){ + lineX.clear(); + lineY.clear(); + lineZ.clear(); + for(int j=0; j<Inner_Wafer_LongitudinalStrips; j++){ + P = P_1_1 + Ref + i*U*TransversePitch + j*V*LongitudinalPitch; + lineX.push_back(P.X()); + lineY.push_back(P.Y()); + lineZ.push_back(P.Z()); + } + + OneDetectorStripPositionX.push_back(lineX); + OneDetectorStripPositionY.push_back(lineY); + OneDetectorStripPositionZ.push_back(lineZ); + } + + m_InnerStripPositionX.push_back(OneDetectorStripPositionX); + m_InnerStripPositionY.push_back(OneDetectorStripPositionY); + m_InnerStripPositionZ.push_back(OneDetectorStripPositionZ); + + // Adding position for upstream silicon: + // Moving to corner of the silicon + P_1_1 = C + +U*0.5*(Inner_PCB_UpstreamWidth-Inner_PCB_DownstreamWidth) // In between wafer + +U*0.5*Inner_PCB_MidWidth // Internal wafer edge + +U*(Inner_Wafer_GuardRing+Inner_Wafer_PADInternal) // Internal active wafer edge + +U*0.5*TransversePitch// middle of strip + -V*0.5*(Inner_PCB_StarboardWidth-Inner_PCB_PortWidth) + -V*0.5*Inner_Wafer_Width + +V*Inner_Wafer_GuardRing + +V*0.5*LongitudinalPitch; // middle of strip + + for(int i=0; i<Inner_Wafer_TransverseStrips; i++){ + lineX.clear(); + lineY.clear(); + lineZ.clear(); + + for(int j=0; j<Inner_Wafer_LongitudinalStrips; j++){ + P = P_1_1 + Ref + i*U*TransversePitch + j*V*LongitudinalPitch; + lineX.push_back(P.X()); + lineY.push_back(P.Y()); + lineZ.push_back(P.Z()); + + } + + m_InnerStripPositionX[m_NumberOfInnerDetectors-1].push_back(lineX); + m_InnerStripPositionY[m_NumberOfInnerDetectors-1].push_back(lineY); + m_InnerStripPositionZ[m_NumberOfInnerDetectors-1].push_back(lineZ); + + } +} + +/////////////////////////////////////////////////////////////////////////// +void TStrassePhysics::AddOuterDetector(double R, double Z, double Phi, double Shift, TVector3 Ref){ + m_NumberOfOuterDetectors++; + double ActiveWidth = Outer_Wafer_Width-2.*Outer_Wafer_GuardRing; + double ActiveLength = Outer_Wafer_Length-Outer_Wafer_PADExternal-Outer_Wafer_PADInternal-2*Outer_Wafer_GuardRing; + double LongitudinalPitch = ActiveWidth/Outer_Wafer_LongitudinalStrips; + double TransversePitch = ActiveLength/Outer_Wafer_TransverseStrips; +//cout << ActiveWidth << " " << ActiveLength << " " << LongitudinalPitch << " " << TransversePitch << endl; + + // Vector C position of detector face center + TVector3 C(Shift,R,Z);// center of the whole detector, including PCB + C.RotateZ(-Phi); + + // Vector W normal to detector face (pointing to the back) + TVector3 W(0,1,0); + W.RotateZ(-Phi); + + // Vector U on detector face (parallel to Z axis/longitudinal strips) + TVector3 U = TVector3(0,0,1); + // Vector V on detector face (parallel to transverse strips) + TVector3 V = W.Cross(U); + + // Adding position for downstream silicon: + // Moving to corner of the silicon + TVector3 P_1_1 = C + +U*0.5*(Outer_PCB_UpstreamWidth-Outer_PCB_DownstreamWidth) // In between wafer + -U*0.5*Outer_PCB_MidWidth // Internal wafer edge + -U*Outer_Wafer_Length // External wafer edge + +U*(Outer_Wafer_GuardRing+Outer_Wafer_PADExternal) // External active wafer edge + +U*0.5*TransversePitch // middle of strip + -V*0.5*(Outer_PCB_StarboardWidth-Outer_PCB_PortWidth) + -V*0.5*Outer_Wafer_Width + +V*Outer_Wafer_GuardRing + +V*0.5*LongitudinalPitch; // middle of strip + + vector<double> lineX; + vector<double> lineY; + vector<double> lineZ; + + vector<vector<double>> OneDetectorStripPositionX; + vector<vector<double>> OneDetectorStripPositionY; + vector<vector<double>> OneDetectorStripPositionZ; + + TVector3 P; + for(int i=0; i<Outer_Wafer_TransverseStrips; i++){ + lineX.clear(); + lineY.clear(); + lineZ.clear(); + for(int j=0; j<Outer_Wafer_LongitudinalStrips; j++){ + P = P_1_1 + Ref + i*U*TransversePitch + j*V*LongitudinalPitch; + lineX.push_back(P.X()); + lineY.push_back(P.Y()); + lineZ.push_back(P.Z()); + } + + OneDetectorStripPositionX.push_back(lineX); + OneDetectorStripPositionY.push_back(lineY); + OneDetectorStripPositionZ.push_back(lineZ); + } + + m_OuterStripPositionX.push_back(OneDetectorStripPositionX); + m_OuterStripPositionY.push_back(OneDetectorStripPositionY); + m_OuterStripPositionZ.push_back(OneDetectorStripPositionZ); + + // Adding position for upstream silicon: + // Moving to corner of the silicon + P_1_1 = C + +U*0.5*(Outer_PCB_UpstreamWidth-Outer_PCB_DownstreamWidth) // In between wafer + +U*0.5*Outer_PCB_MidWidth // Internal wafer edge + +U*(Outer_Wafer_GuardRing+Outer_Wafer_PADInternal) // Internal active wafer edge + +U*0.5*TransversePitch// middle of strip + -V*0.5*(Outer_PCB_StarboardWidth-Outer_PCB_PortWidth) + -V*0.5*Outer_Wafer_Width + +V*Outer_Wafer_GuardRing + +V*0.5*LongitudinalPitch; // middle of strip + + for(int i=0; i<Outer_Wafer_TransverseStrips; i++){ + lineX.clear(); + lineY.clear(); + lineZ.clear(); + + for(int j=0; j<Outer_Wafer_LongitudinalStrips; j++){ + P = P_1_1 + Ref + i*U*TransversePitch + j*V*LongitudinalPitch; + lineX.push_back(P.X()); + lineY.push_back(P.Y()); + lineZ.push_back(P.Z()); + + } + + m_OuterStripPositionX[m_NumberOfOuterDetectors-1].push_back(lineX); + m_OuterStripPositionY[m_NumberOfOuterDetectors-1].push_back(lineY); + m_OuterStripPositionZ[m_NumberOfOuterDetectors-1].push_back(lineZ); + + } +} + + +/////////////////////////////////////////////////////////////////////////// +TVector3 TStrassePhysics::GetInnerPositionOfInteraction(const int i){ + TVector3 Position = TVector3( + GetInnerStripPositionX(DetectorNumber[i], InnerStripT[i], InnerStripL[i]), + GetInnerStripPositionY(DetectorNumber[i], InnerStripT[i], InnerStripL[i]), + GetInnerStripPositionZ(DetectorNumber[i], InnerStripT[i], InnerStripL[i])); + + return Position; +} + +/////////////////////////////////////////////////////////////////////////// +TVector3 TStrassePhysics::GetOuterPositionOfInteraction(const int i){ + TVector3 Position = TVector3(GetOuterStripPositionX(DetectorNumber[i], OuterStripT[i], OuterStripL[i]), + GetOuterStripPositionY(DetectorNumber[i], OuterStripT[i], OuterStripL[i]), + GetOuterStripPositionZ(DetectorNumber[i], OuterStripT[i], OuterStripL[i])); + + return Position; +} + + +/////////////////////////////////////////////////////////////////////////// +TVector3 TStrassePhysics::GetDetectorNormal(const int i){ + // TVector3 U = TVector3(GetStripPositionX(DetectorNumber[i],128,1), + // GetStripPositionY(DetectorNumber[i],128,1), + // GetStripPositionZ(DetectorNumber[i],128,1)) + // + // -TVector3(GetStripPositionX(DetectorNumber[i],1,1), + // GetStripPositionY(DetectorNumber[i],1,1), + // GetStripPositionZ(DetectorNumber[i],1,1)); + // + // TVector3 V = TVector3(GetStripPositionX(DetectorNumber[i],128,128), + // GetStripPositionY(DetectorNumber[i],128,128), + // GetStripPositionZ(DetectorNumber[i],128,128)) + // + // -TVector3(GetStripPositionX(DetectorNumber[i],128,1), + // GetStripPositionY(DetectorNumber[i],128,1), + // GetStripPositionZ(DetectorNumber[i],128,1)); + // + // TVector3 Normal = U.Cross(V); + // + // return (Normal.Unit()); + return TVector3(0,0,0); +} +/////////////////////////////////////////////////////////////////////////// +void TStrassePhysics::BuildSimplePhysicalEvent() { + BuildPhysicalEvent(); +} + + + +/////////////////////////////////////////////////////////////////////////// +void TStrassePhysics::BuildPhysicalEvent() { + // apply thresholds and calibration + PreTreat(); + + if(1 /*CheckEvent() == 1*/){ + vector<TVector2> inner = MatchInner(); + vector<TVector2> outer = MatchOuter(); + + for(unsigned int i=0; i<inner.size(); i++){ + int N = m_PreTreatedData->GetInner_TE_DetectorNbr(inner[i].X()); + int innerT = m_PreTreatedData->GetInner_TE_StripNbr(inner[i].X()); + int innerL = m_PreTreatedData->GetInner_LE_StripNbr(inner[i].Y()); + + double TE = m_PreTreatedData->GetInner_TE_Energy(inner[i].X()); + // look for outer + double outerE = 0; + int outerT=0; + int outerL=0; + for(unsigned int j=0; j<outer.size(); j++){ + if(m_PreTreatedData->GetInner_TE_DetectorNbr(outer[j].X())==N){ + outerE = m_PreTreatedData->GetOuter_TE_Energy(outer[j].X()); + outerT = m_PreTreatedData->GetOuter_TE_StripNbr(outer[j].X()); + outerL = m_PreTreatedData->GetOuter_LE_StripNbr(outer[j].Y()); + } + } + + if(outerE){ + EventMultiplicity++; + DetectorNumber.push_back(N); + InnerStripT.push_back(innerT); + InnerStripL.push_back(innerL); + DE.push_back(TE); + InnerPosX.push_back(GetInnerPositionOfInteraction(EventMultiplicity-1).x()); + InnerPosY.push_back(GetInnerPositionOfInteraction(EventMultiplicity-1).y()); + InnerPosZ.push_back(GetInnerPositionOfInteraction(EventMultiplicity-1).z()); + + OuterStripT.push_back(outerT); + OuterStripL.push_back(outerL); + E.push_back(outerE); + OuterPosX.push_back(GetOuterPositionOfInteraction(EventMultiplicity-1).x()); + OuterPosY.push_back(GetOuterPositionOfInteraction(EventMultiplicity-1).y()); + OuterPosZ.push_back(GetOuterPositionOfInteraction(EventMultiplicity-1).z()); + } + + } + } + +} + +/////////////////////////////////////////////////////////////////////////// +vector<TVector2> TStrassePhysics::MatchInner(){ + vector<TVector2> ArrayOfGoodCouple; + + static unsigned int m_TEMult, m_LEMult; + m_TEMult = m_PreTreatedData->GetInnerMultTEnergy(); + m_LEMult = m_PreTreatedData->GetInnerMultLEnergy(); + + if(m_TEMult>m_MaximumStripMultiplicityAllowed || m_LEMult>m_MaximumStripMultiplicityAllowed){ + return ArrayOfGoodCouple; + } + + for(unsigned int i=0; i<m_TEMult; i++){ + for(unsigned int j=0; j<m_LEMult; j++){ + + // Declaration of variable for clarity + int XDetNbr = m_PreTreatedData->GetInner_TE_DetectorNbr(i); + int YDetNbr = m_PreTreatedData->GetInner_LE_DetectorNbr(j); + + // if same detector check energy + if(XDetNbr == YDetNbr){ + // Declaration of variable for clarity + double TE = m_PreTreatedData->GetInner_TE_Energy(i); + double LE = m_PreTreatedData->GetInner_LE_Energy(j); + + // look if energy matches + if(abs(TE-LE)/2.<m_StripEnergyMatching){ + ArrayOfGoodCouple.push_back(TVector2(i,j)); + } + } + } + } + + return ArrayOfGoodCouple; +} +/////////////////////////////////////////////////////////////////////////// +vector<TVector2> TStrassePhysics::MatchOuter(){ + vector<TVector2> ArrayOfGoodCouple; + + static unsigned int m_TEMult, m_LEMult; + m_TEMult = m_PreTreatedData->GetOuterMultTEnergy(); + m_LEMult = m_PreTreatedData->GetOuterMultLEnergy(); + + if(m_TEMult>m_MaximumStripMultiplicityAllowed || m_LEMult>m_MaximumStripMultiplicityAllowed){ + return ArrayOfGoodCouple; + } + + for(unsigned int i=0; i<m_TEMult; i++){ + for(unsigned int j=0; j<m_LEMult; j++){ + + // Declaration of variable for clarity + int XDetNbr = m_PreTreatedData->GetOuter_TE_DetectorNbr(i); + int YDetNbr = m_PreTreatedData->GetOuter_LE_DetectorNbr(j); + + // if same detector check energy + if(XDetNbr == YDetNbr){ + // Declaration of variable for clarity + double TE = m_PreTreatedData->GetOuter_TE_Energy(i); + double LE = m_PreTreatedData->GetOuter_LE_Energy(j); + + // look if energy matches + if(abs(TE-LE)/2.<m_StripEnergyMatching){ + ArrayOfGoodCouple.push_back(TVector2(i,j)); + } + } + } + } + + return ArrayOfGoodCouple; +} + + +/////////////////////////////////////////////////////////////////////////// +int TStrassePhysics::CheckEvent(){ + // Check the size of the different elements + if(m_PreTreatedData->GetInnerMultTEnergy() == m_PreTreatedData->GetInnerMultLEnergy() ) + return 1; + + else + return -1; +} + + +/////////////////////////////////////////////////////////////////////////// +void TStrassePhysics::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(); + + ////// + // First Stage Energy + unsigned int sizeFront = m_EventData->GetInnerMultTEnergy(); + for (UShort_t i = 0; i < sizeFront ; ++i) { + if (m_EventData->GetInner_TE_Energy(i) > m_E_RAW_Threshold) { + Double_t Energy = m_EventData->GetInner_TE_Energy(i); + //Double_t Energy = Cal->ApplyCalibration("Strasse/ENERGY"+NPL::itoa(m_EventData->GetInner_TE_DetectorNbr(i)),m_EventData->GetInner_TE_Energy(i)); + if (Energy > m_E_Threshold) { + m_PreTreatedData->SetInnerTE(m_EventData->GetInner_TE_DetectorNbr(i), m_EventData->GetInner_TE_StripNbr(i), Energy); + } + } + } + unsigned int sizeBack = m_EventData->GetInnerMultTEnergy(); + for (UShort_t i = 0; i < sizeBack ; ++i) { + if (m_EventData->GetInner_LE_Energy(i) > m_E_RAW_Threshold) { + Double_t Energy = m_EventData->GetInner_LE_Energy(i); + //Double_t Energy = Cal->ApplyCalibration("Strasse/ENERGY"+NPL::itoa(m_EventData->GetInner_LE_DetectorNbr(i)),m_EventData->GetInner_LE_Energy(i)); + if (Energy > m_E_Threshold) { + m_PreTreatedData->SetInnerLE(m_EventData->GetInner_LE_DetectorNbr(i), m_EventData->GetInner_LE_StripNbr(i), Energy); + } + } + } + + ////// + // Second Stage Energy + sizeFront = m_EventData->GetOuterMultTEnergy(); + for (UShort_t i = 0; i < sizeFront ; ++i) { + if (m_EventData->GetOuter_TE_Energy(i) > m_E_RAW_Threshold) { + Double_t Energy = m_EventData->GetOuter_TE_Energy(i); + //Double_t Energy = Cal->ApplyCalibration("Strasse/ENERGY"+NPL::itoa(m_EventData->GetOuter_TE_DetectorNbr(i)),m_EventData->GetOuter_TE_Energy(i)); + if (Energy > m_E_Threshold) { + m_PreTreatedData->SetOuterTE(m_EventData->GetOuter_TE_DetectorNbr(i), m_EventData->GetOuter_TE_StripNbr(i), Energy); + } + } + } + sizeBack = m_EventData->GetOuterMultTEnergy(); + for (UShort_t i = 0; i < sizeBack ; ++i) { + if (m_EventData->GetOuter_LE_Energy(i) > m_E_RAW_Threshold) { + Double_t Energy = m_EventData->GetOuter_LE_Energy(i); + //Double_t Energy = Cal->ApplyCalibration("Strasse/ENERGY"+NPL::itoa(m_EventData->GetOuter_LE_DetectorNbr(i)),m_EventData->GetOuter_LE_Energy(i)); + if (Energy > m_E_Threshold) { + m_PreTreatedData->SetOuterLE(m_EventData->GetOuter_LE_DetectorNbr(i), m_EventData->GetOuter_LE_StripNbr(i), Energy); + } + } + } + +} + + + +/////////////////////////////////////////////////////////////////////////// +void TStrassePhysics::ReadAnalysisConfig() { + bool ReadingStatus = false; + + // path to file + string FileName = "./configs/ConfigStrasse.dat"; + + // open analysis config file + ifstream AnalysisConfigFile; + AnalysisConfigFile.open(FileName.c_str()); + + if (!AnalysisConfigFile.is_open()) { + cout << " No ConfigStrasse.dat found: Default parameter loaded for Analayis " << FileName << endl; + return; + } + cout << " Loading user parameter for Analysis from ConfigStrasse.dat " << endl; + + // Save it in a TAsciiFile + TAsciiFile* asciiConfig = RootOutput::getInstance()->GetAsciiFileAnalysisConfig(); + asciiConfig->AppendLine("%%% ConfigStrasse.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 = "ConfigStrasse"; + 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 TStrassePhysics::Clear() { + EventMultiplicity = 0; + // DSSD + DetectorNumber.clear(); + E.clear(); + InnerStripT.clear(); + InnerStripL.clear(); + OuterStripT.clear(); + OuterStripL.clear(); + DE.clear(); + + // Position Information + InnerPosX.clear(); + InnerPosY.clear(); + InnerPosZ.clear(); + OuterPosX.clear(); + OuterPosY.clear(); + OuterPosZ.clear(); + + +} + + + +/////////////////////////////////////////////////////////////////////////// +void TStrassePhysics::ReadConfiguration(NPL::InputParser parser) { + // Info block + vector<NPL::InputBlock*> blocks_info = parser.GetAllBlocksWithTokenAndValue("Strasse","Info"); + if(NPOptionManager::getInstance()->GetVerboseLevel()) + cout << "//// " << blocks_info.size() << " info block founds " << endl; + + if(blocks_info.size()>1){ + cout << "ERROR: can only accepte one info block, " << blocks_info.size() << " info block founds." << endl; + exit(1); + } + + vector<string> info = { + "Inner_Wafer_Length", + "Inner_Wafer_Width", + "Inner_Wafer_Thickness", + "Inner_Wafer_AlThickness", + "Inner_Wafer_PADExternal", + "Inner_Wafer_PADInternal", + "Inner_Wafer_GuardRing", + "Inner_PCB_PortWidth", + "Inner_PCB_StarboardWidth", + "Inner_PCB_BevelAngle", + "Inner_PCB_UpstreamWidth", + "Inner_PCB_DownstreamWidth", + "Inner_PCB_MidWidth", + "Inner_PCB_Thickness", + "Inner_Wafer_TransverseStrips", + "Inner_Wafer_LongitudinalStrips", + "Outer_Wafer_Length", + "Outer_Wafer_Width", + "Outer_Wafer_Thickness", + "Outer_Wafer_AlThickness", + "Outer_Wafer_PADExternal", + "Outer_Wafer_PADInternal", + "Outer_Wafer_GuardRing", + "Outer_PCB_PortWidth", + "Outer_PCB_StarboardWidth", + "Outer_PCB_BevelAngle", + "Outer_PCB_UpstreamWidth", + "Outer_PCB_DownstreamWidth", + "Outer_PCB_MidWidth", + "Outer_PCB_Thickness", + "Outer_Wafer_TransverseStrips", + "Outer_Wafer_LongitudinalStrips" + }; + + if(blocks_info[0]->HasTokenList(info)){ + cout << endl << "//// Strasse info block" << endl; + Inner_Wafer_Length = blocks_info[0]->GetDouble("Inner_Wafer_Length","mm"); + Inner_Wafer_Width = blocks_info[0]->GetDouble("Inner_Wafer_Width","mm"); + Inner_Wafer_Thickness = blocks_info[0]->GetDouble("Inner_Wafer_Thickness","micrometer"); + Inner_Wafer_AlThickness = blocks_info[0]->GetDouble("Inner_Wafer_AlThickness","micrometer"); + Inner_Wafer_PADExternal = blocks_info[0]->GetDouble("Inner_Wafer_PADExternal","mm"); + Inner_Wafer_PADInternal = blocks_info[0]->GetDouble("Inner_Wafer_PADInternal","mm"); + Inner_Wafer_GuardRing = blocks_info[0]->GetDouble("Inner_Wafer_GuardRing","mm"); + Inner_Wafer_TransverseStrips = blocks_info[0]->GetInt("Inner_Wafer_TransverseStrips"); + Inner_Wafer_LongitudinalStrips = blocks_info[0]->GetInt("Inner_Wafer_LongitudinalStrips"); + Inner_PCB_PortWidth = blocks_info[0]->GetDouble("Inner_PCB_PortWidth","mm"); + Inner_PCB_StarboardWidth = blocks_info[0]->GetDouble("Inner_PCB_StarboardWidth","mm"); + Inner_PCB_BevelAngle = blocks_info[0]->GetDouble("Inner_PCB_BevelAngle","mm"); + Inner_PCB_UpstreamWidth = blocks_info[0]->GetDouble("Inner_PCB_UpstreamWidth","mm"); + Inner_PCB_DownstreamWidth = blocks_info[0]->GetDouble("Inner_PCB_DownstreamWidth","mm"); + Inner_PCB_MidWidth = blocks_info[0]->GetDouble("Inner_PCB_MidWidth","mm"); + Inner_PCB_Thickness = blocks_info[0]->GetDouble("Inner_PCB_Thickness","mm"); + Outer_Wafer_Length = blocks_info[0]->GetDouble("Outer_Wafer_Length","mm"); + Outer_Wafer_Width = blocks_info[0]->GetDouble("Outer_Wafer_Width","mm"); + Outer_Wafer_Thickness = blocks_info[0]->GetDouble("Outer_Wafer_Thickness","mm"); + Outer_Wafer_AlThickness = blocks_info[0]->GetDouble("Outer_Wafer_AlThickness","micrometer"); + Outer_Wafer_PADExternal = blocks_info[0]->GetDouble("Outer_Wafer_PADExternal","mm"); + Outer_Wafer_PADInternal = blocks_info[0]->GetDouble("Outer_Wafer_PADInternal","mm"); + Outer_Wafer_GuardRing = blocks_info[0]->GetDouble("Outer_Wafer_GuardRing","mm"); + Outer_Wafer_TransverseStrips = blocks_info[0]->GetInt("Outer_Wafer_TransverseStrips"); + Outer_Wafer_LongitudinalStrips = blocks_info[0]->GetInt("Outer_Wafer_LongitudinalStrips"); + Outer_PCB_PortWidth = blocks_info[0]->GetDouble("Outer_PCB_PortWidth","mm"); + Outer_PCB_StarboardWidth = blocks_info[0]->GetDouble("Outer_PCB_StarboardWidth","mm"); + Outer_PCB_BevelAngle = blocks_info[0]->GetDouble("Outer_PCB_BevelAngle","deg"); + Outer_PCB_UpstreamWidth = blocks_info[0]->GetDouble("Outer_PCB_UpstreamWidth","mm"); + Outer_PCB_DownstreamWidth = blocks_info[0]->GetDouble("Outer_PCB_DownstreamWidth","mm"); + Outer_PCB_MidWidth = blocks_info[0]->GetDouble("Outer_PCB_MidWidth","mm"); + Outer_PCB_Thickness = blocks_info[0]->GetDouble("Outer_PCB_Thickness","mm"); + + } + + else{ + cout << "ERROR: check your input file formatting " << endl; + exit(1); + } + + + // Inner Barrel + vector<NPL::InputBlock*> blocks_inner = parser.GetAllBlocksWithTokenAndValue("Strasse","Inner"); + if(NPOptionManager::getInstance()->GetVerboseLevel()) + cout << "//// " << blocks_inner.size() << " inner detectors found " << endl; + + vector<string> coord = {"Radius","Z","Phi","Shift"}; + + for(unsigned int i = 0 ; i < blocks_inner.size() ; i++){ + if(blocks_inner[i]->HasTokenList(coord)){ + if(NPOptionManager::getInstance()->GetVerboseLevel()) + cout << endl << "//// Strasse inner detector" << i+1 << endl; + + double R = blocks_inner[i]->GetDouble("Radius","mm"); + double Z= blocks_inner[i]->GetDouble("Z","mm"); + double Phi = blocks_inner[i]->GetDouble("Phi","deg"); + double Shift = blocks_inner[i]->GetDouble("Shift","mm"); + TVector3 Ref = blocks_inner[i]->GetTVector3("Ref","mm"); + AddInnerDetector(R,Z,Phi,Shift,Ref); + } + else{ + cout << "ERROR: check your input file formatting on " << i+1 << " inner block " <<endl; + exit(1); + } + } + + // Outer barrel + vector<NPL::InputBlock*> blocks_outer = parser.GetAllBlocksWithTokenAndValue("Strasse","Outer"); + if(NPOptionManager::getInstance()->GetVerboseLevel()) + cout << "//// " << blocks_outer.size() << " outer detectors found " << endl; + + for(unsigned int i = 0 ; i < blocks_outer.size() ; i++){ + if(blocks_outer[i]->HasTokenList(coord)){ + if(NPOptionManager::getInstance()->GetVerboseLevel()) + cout << endl << "//// Strasse outer detector" << i+1 << endl; + + double R = blocks_outer[i]->GetDouble("Radius","mm"); + double Z= blocks_outer[i]->GetDouble("Z","mm"); + double Phi = blocks_outer[i]->GetDouble("Phi","deg"); + double Shift = blocks_outer[i]->GetDouble("Shift","mm"); + TVector3 Ref = blocks_outer[i]->GetTVector3("Ref","mm"); + AddOuterDetector(R,Z,Phi,Shift,Ref); + } + else{ + + cout << "ERROR: check your input file formatting on " << i+1 << " outer block " <<endl; + exit(1); + } + } + +} + +/////////////////////////////////////////////////////////////////////////// +void TStrassePhysics::InitSpectra() { + // m_Spectra = new TStrasseSpectra(m_NumberOfInnerDetectors); +} + + + +/////////////////////////////////////////////////////////////////////////// +void TStrassePhysics::FillSpectra() { + m_Spectra -> FillRawSpectra(m_EventData); + m_Spectra -> FillPreTreatedSpectra(m_PreTreatedData); + m_Spectra -> FillPhysicsSpectra(m_EventPhysics); +} + + + +/////////////////////////////////////////////////////////////////////////// +void TStrassePhysics::CheckSpectra() { + m_Spectra->CheckSpectra(); +} + + + +/////////////////////////////////////////////////////////////////////////// +void TStrassePhysics::ClearSpectra() { + // To be done +} + + + +/////////////////////////////////////////////////////////////////////////// +map< string , TH1*> TStrassePhysics::GetSpectra() { + if(m_Spectra) + return m_Spectra->GetMapHisto(); + else{ + map< string , TH1*> empty; + return empty; + } +} + +/////////////////////////////////////////////////////////////////////////// +void TStrassePhysics::WriteSpectra() { + m_Spectra->WriteSpectra(); +} + + + +/////////////////////////////////////////////////////////////////////////// +void TStrassePhysics::AddParameterToCalibrationManager() { + CalibrationManager* Cal = CalibrationManager::getInstance(); + /* for (int i = 0; i < m_NumberOfInnerDetectors; ++i) { + Cal->AddParameter("Strasse", "INNER"+ NPL::itoa(i+1)+"_ENERGY","Strasse_INNER"+ NPL::itoa(i+1)+"_ENERGY"); + } + for (int i = 0; i < m_NumberOfInnerDetectors; ++i) { + Cal->AddParameter("Strasse", "OUTER"+ NPL::itoa(i+1)+"_ENERGY","Strasse_OUTER"+ NPL::itoa(i+1)+"_ENERGY"); + } + */ +} + + + +/////////////////////////////////////////////////////////////////////////// +void TStrassePhysics::InitializeRootInputRaw() { + TChain* inputChain = RootInput::getInstance()->GetChain(); + inputChain->SetBranchStatus("Strasse", true ); + inputChain->SetBranchAddress("Strasse", &m_EventData ); +} + + + +/////////////////////////////////////////////////////////////////////////// +void TStrassePhysics::InitializeRootInputPhysics() { + TChain* inputChain = RootInput::getInstance()->GetChain(); + inputChain->SetBranchAddress("Strasse", &m_EventPhysics); +} + + + +/////////////////////////////////////////////////////////////////////////// +void TStrassePhysics::InitializeRootOutput() { + TTree* outputTree = RootOutput::getInstance()->GetTree(); + outputTree->Branch("Strasse", "TStrassePhysics", &m_EventPhysics); +} + + + +//////////////////////////////////////////////////////////////////////////////// +// Construct Method to be pass to the DetectorFactory // +//////////////////////////////////////////////////////////////////////////////// +NPL::VDetector* TStrassePhysics::Construct() { + return (NPL::VDetector*) new TStrassePhysics(); +} + + + +//////////////////////////////////////////////////////////////////////////////// +// Registering the construct method to the factory // +//////////////////////////////////////////////////////////////////////////////// +extern "C"{ + class proxy_Strasse{ + public: + proxy_Strasse(){ + NPL::DetectorFactory::getInstance()->AddToken("Strasse","Strasse"); + NPL::DetectorFactory::getInstance()->AddDetector("Strasse",TStrassePhysics::Construct); + } + }; + + proxy_Strasse p_Strasse; +} + diff --git a/NPLib/Detectors/Strasse/TStrassePhysics.h b/NPLib/Detectors/Strasse/TStrassePhysics.h new file mode 100644 index 0000000000000000000000000000000000000000..a50c24a59b4f0f1d49a566f9ed90c778ce19e033 --- /dev/null +++ b/NPLib/Detectors/Strasse/TStrassePhysics.h @@ -0,0 +1,290 @@ +#ifndef TStrassePHYSICS_H +#define TStrassePHYSICS_H +/***************************************************************************** + * Copyright (C) 2009-2020 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: F. Flavigny contact : flavigny@lpccaen.in2p3.fr * + * * + * Creation Date : July 2020 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class hold Strasse 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 "TStrasseData.h" +#include "TStrasseSpectra.h" +#include "NPCalibrationManager.h" +#include "NPVDetector.h" +#include "NPInputParser.h" +// forward declaration +class TStrasseSpectra; + + + +class TStrassePhysics : public TObject, public NPL::VDetector { + ////////////////////////////////////////////////////////////// + // constructor and destructor + public: + TStrassePhysics(); + ~TStrassePhysics() {}; + + + ////////////////////////////////////////////////////////////// + // Inherited from TObject and overriden to avoid warnings + public: + void Clear(); + void Clear(const Option_t*) {}; + + public: + vector<TVector2> MatchInner(); + vector<TVector2> MatchOuter(); + int CheckEvent(); + + ////////////////////////////////////////////////////////////// + // data obtained after BuildPhysicalEvent() and stored in + // output ROOT file + public: + Int_t EventMultiplicity; + vector<int> DetectorNumber; + vector<double> E; + vector<double> DE; + vector<int> InnerStripT; + vector<int> InnerStripL; + vector<int> OuterStripT; + vector<int> OuterStripL; + + + vector<double> InnerPosX; + vector<double> InnerPosY; + vector<double> InnerPosZ; + vector<double> OuterPosX; + vector<double> OuterPosY; + vector<double> OuterPosZ; + + + + ////////////////////////////////////////////////////////////// + // methods inherited from the VDetector ABC class + public: + // read stream from ConfigFile to pick-up detector parameters + void ReadConfiguration(NPL::InputParser); + + /// A usefull method to bundle all operation to add a detector + void AddInnerDetector(double R, double Z, double Phi,double Shift,TVector3 Ref); + void AddOuterDetector(double R, double Z, double Phi,double Shift,TVector3 Ref); + + // 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 TStrasseSpectra class + // instantiate the TStrasseSpectra 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 Strasse 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 TStrasseData object to TStrassePhysics. + // needed for online analysis for example + void SetRawDataPointer(TStrasseData* rawDataPointer) {m_EventData = rawDataPointer;} + + double GetNumberOfInnerDetector() const {return m_NumberOfInnerDetectors;} + double GetNumberOfOuterDetector() const {return m_NumberOfOuterDetectors;} + int GetEventMultiplicity() const {return EventMultiplicity;} + + double GetInnerStripPositionX(const int N, const int X, const int Y){ + return m_InnerStripPositionX[N-1][X-1][Y-1]; + }; + double GetInnerStripPositionY(const int N, const int X, const int Y){ + return m_InnerStripPositionY[N-1][X-1][Y-1]; + }; + double GetInnerStripPositionZ(const int N, const int X, const int Y){ + return m_InnerStripPositionZ[N-1][X-1][Y-1]; + }; + + double GetOuterStripPositionX(const int N, const int X, const int Y){ + return m_OuterStripPositionX[N-1][X-1][Y-1]; + }; + double GetOuterStripPositionY(const int N, const int X, const int Y){ + return m_OuterStripPositionY[N-1][X-1][Y-1]; + }; + double GetOuterStripPositionZ(const int N, const int X, const int Y){ + return m_OuterStripPositionZ[N-1][X-1][Y-1]; + }; + + TVector3 GetInnerPositionOfInteraction(const int i); + TVector3 GetOuterPositionOfInteraction(const int i); + + TVector3 GetDetectorNormal(const int i); + + // objects are not written in the TTree + private: + TStrasseData* m_EventData; //! + TStrasseData* m_PreTreatedData; //! + TStrassePhysics* m_EventPhysics; //! + + // getters for raw and pre-treated data object + public: + TStrasseData* GetRawData() const {return m_EventData;} + TStrasseData* GetPreTreatedData() const {return m_PreTreatedData;} + + // parameters used in the analysis + private: + int m_NumberOfInnerDetectors; //! + int m_NumberOfOuterDetectors; //! + + vector<vector<vector<double>>> m_InnerStripPositionX; //! + vector<vector<vector<double>>> m_InnerStripPositionY; //! + vector<vector<vector<double>>> m_InnerStripPositionZ; //! + + vector<vector<vector<double>>> m_OuterStripPositionX; //! + vector<vector<vector<double>>> m_OuterStripPositionY; //! + vector<vector<vector<double>>> m_OuterStripPositionZ; //! + + + // thresholds + double m_E_RAW_Threshold; //! + double m_E_Threshold; //! + + private: + unsigned int m_MaximumStripMultiplicityAllowed;// + double m_StripEnergyMatching;// + + + // spectra class + private: + TStrasseSpectra* m_Spectra; // ! + + // spectra getter + public: + map<string, TH1*> GetSpectra(); + + // Static constructor to be passed to the Detector Factory + public: + static NPL::VDetector* Construct(); + + ClassDef(TStrassePhysics,1) // StrassePhysics structure + + private: // geometry + //////////////////// + // Inner Detector // + //////////////////// + // Wafer parameter + double Inner_Wafer_Length; + double Inner_Wafer_Width; + double Inner_Wafer_Thickness; + double Inner_Wafer_AlThickness; + double Inner_Wafer_PADExternal; + double Inner_Wafer_PADInternal; + double Inner_Wafer_GuardRing; + + // PCB parameter + double Inner_PCB_PortWidth; + double Inner_PCB_StarboardWidth; + double Inner_PCB_BevelAngle; + double Inner_PCB_UpstreamWidth; + double Inner_PCB_DownstreamWidth; + double Inner_PCB_MidWidth; + double Inner_PCB_Thickness; + double Inner_Wafer_TransverseStrips; + double Inner_Wafer_LongitudinalStrips; + + //////////////////// + // Outer Detector // + //////////////////// + // Wafer parameter + double Outer_Wafer_Length; + double Outer_Wafer_Width; + double Outer_Wafer_Thickness; + double Outer_Wafer_AlThickness; + double Outer_Wafer_PADExternal; + double Outer_Wafer_PADInternal; + double Outer_Wafer_GuardRing; + + // PCB parameter + double Outer_PCB_PortWidth; + double Outer_PCB_StarboardWidth; + double Outer_PCB_BevelAngle; + double Outer_PCB_UpstreamWidth; + double Outer_PCB_DownstreamWidth; + double Outer_PCB_MidWidth; + double Outer_PCB_Thickness; + double Outer_Wafer_TransverseStrips; + double Outer_Wafer_LongitudinalStrips; + + +}; +#endif diff --git a/NPLib/Detectors/Strasse/TStrasseSpectra.cxx b/NPLib/Detectors/Strasse/TStrasseSpectra.cxx new file mode 100644 index 0000000000000000000000000000000000000000..64edd19ce58d7f06e918a5132c49cfc8881437fb --- /dev/null +++ b/NPLib/Detectors/Strasse/TStrasseSpectra.cxx @@ -0,0 +1,149 @@ +/***************************************************************************** + * Copyright (C) 2009-2020 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: F. Flavigny contact : flavigny@lpccaen.in2p3.fr * + * * + * Creation Date : May 2020 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class hold Strasse Spectra * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + * * + *****************************************************************************/ + +// class header +#include "TStrasseSpectra.h" + +// STL +#include <iostream> +#include <string> +using namespace std; + +// NPTool header +#include "NPOptionManager.h" + + + +//////////////////////////////////////////////////////////////////////////////// +TStrasseSpectra::TStrasseSpectra() + : fNumberOfDetectors(0) { + SetName("Strasse"); +} + + + +//////////////////////////////////////////////////////////////////////////////// +TStrasseSpectra::TStrasseSpectra(unsigned int NumberOfDetectors) { + if(NPOptionManager::getInstance()->GetVerboseLevel()>0) + cout << "************************************************" << endl + << "TStrasseSpectra : Initalizing control spectra for " + << NumberOfDetectors << " Detectors" << endl + << "************************************************" << endl ; + SetName("Strasse"); + fNumberOfDetectors = NumberOfDetectors; + + InitRawSpectra(); + InitPreTreatedSpectra(); + InitPhysicsSpectra(); +} + + + +//////////////////////////////////////////////////////////////////////////////// +TStrasseSpectra::~TStrasseSpectra() { +} + + + +//////////////////////////////////////////////////////////////////////////////// +void TStrasseSpectra::InitRawSpectra() { + static string name; + for (unsigned int i = 0; i < fNumberOfDetectors; i++) { // loop on number of detectors + // Energy + name = "Strasse"+NPL::itoa(i+1)+"_ENERGY_RAW"; + AddHisto1D(name, name, 4096, 0, 16384, "Strasse/RAW"); + } // end loop on number of detectors +} + + + +//////////////////////////////////////////////////////////////////////////////// +void TStrasseSpectra::InitPreTreatedSpectra() { + static string name; + for (unsigned int i = 0; i < fNumberOfDetectors; i++) { // loop on number of detectors + // Energy + name = "Strasse"+NPL::itoa(i+1)+"_ENERGY_CAL"; + AddHisto1D(name, name, 500, 0, 25, "Strasse/CAL"); + } // end loop on number of detectors +} + + + +//////////////////////////////////////////////////////////////////////////////// +void TStrasseSpectra::InitPhysicsSpectra() { + static string name; + // Kinematic Plot + name = "Strasse_ENERGY_TIME"; + AddHisto2D(name, name, 500, 0, 500, 500, 0, 50, "Strasse/PHY"); +} + + + +//////////////////////////////////////////////////////////////////////////////// +void TStrasseSpectra::FillRawSpectra(TStrasseData* RawData) { + static string name; + static string family; + + // Energy + unsigned int sizeE = RawData->GetInnerMultTEnergy(); + for (unsigned int i = 0; i < sizeE; i++) { + name = "Strasse"+NPL::itoa(RawData->GetInner_TE_DetectorNbr(i))+"_ENERGY_RAW"; + family = "Strasse/RAW"; + + FillSpectra(family,name,RawData->GetInner_TE_Energy(i)); + } + +} + + + +//////////////////////////////////////////////////////////////////////////////// +void TStrasseSpectra::FillPreTreatedSpectra(TStrasseData* PreTreatedData) { + static string name; + static string family; + + // Energy + unsigned int sizeE = PreTreatedData->GetInnerMultTEnergy(); + for (unsigned int i = 0; i < sizeE; i++) { + name = "Strasse"+NPL::itoa(PreTreatedData->GetInner_TE_DetectorNbr(i))+"_ENERGY_CAL"; + family = "Strasse/CAL"; + + FillSpectra(family,name,PreTreatedData->GetInner_TE_Energy(i)); + } +} + + + +//////////////////////////////////////////////////////////////////////////////// +void TStrasseSpectra::FillPhysicsSpectra(TStrassePhysics* Physics) { + static string name; + static string family; + family= "Strasse/PHY"; + + // Energy vs time + unsigned int sizeE = Physics->E.size(); + for(unsigned int i = 0 ; i < sizeE ; i++){ + //name = "Strasse_ENERGY_TIME"; + //FillSpectra(family,name,Physics->E[i],Physics->Time[i]); + } +} + diff --git a/NPLib/Detectors/Strasse/TStrasseSpectra.h b/NPLib/Detectors/Strasse/TStrasseSpectra.h new file mode 100644 index 0000000000000000000000000000000000000000..81596b68ead6689ed0b0e487ea4269cb452ea065 --- /dev/null +++ b/NPLib/Detectors/Strasse/TStrasseSpectra.h @@ -0,0 +1,62 @@ +#ifndef TStrasseSPECTRA_H +#define TStrasseSPECTRA_H +/***************************************************************************** + * Copyright (C) 2009-2020 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: F. Flavigny contact : flavigny@lpccaen.in2p3.fr * + * * + * Creation Date : July 2020 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class hold Strasse Spectra * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + * * + *****************************************************************************/ + +// NPLib headers +#include "NPVSpectra.h" +#include "TStrasseData.h" +#include "TStrassePhysics.h" + +// Forward Declaration +class TStrassePhysics; + + +class TStrasseSpectra : public VSpectra { + ////////////////////////////////////////////////////////////// + // constructor and destructor + public: + TStrasseSpectra(); + TStrasseSpectra(unsigned int NumberOfDetectors); + ~TStrasseSpectra(); + + ////////////////////////////////////////////////////////////// + // Initialization methods + private: + void InitRawSpectra(); + void InitPreTreatedSpectra(); + void InitPhysicsSpectra(); + + ////////////////////////////////////////////////////////////// + // Filling methods + public: + void FillRawSpectra(TStrasseData*); + void FillPreTreatedSpectra(TStrasseData*); + void FillPhysicsSpectra(TStrassePhysics*); + + ////////////////////////////////////////////////////////////// + // Detector parameters + private: + unsigned int fNumberOfDetectors; +}; + +#endif diff --git a/NPLib/Detectors/TACTIC/CMakeLists.txt b/NPLib/Detectors/TACTIC/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..ee7f804d8716f08e376a270f837e2125bf392b2c --- /dev/null +++ b/NPLib/Detectors/TACTIC/CMakeLists.txt @@ -0,0 +1,6 @@ +add_custom_command(OUTPUT TTACTICPhysicsDict.cxx COMMAND ../../scripts/build_dict.sh TTACTICPhysics.h TTACTICPhysicsDict.cxx TTACTICPhysics.rootmap libNPTACTIC.dylib DEPENDS TTACTICPhysics.h) +add_custom_command(OUTPUT TTACTICDataDict.cxx COMMAND ../../scripts/build_dict.sh TTACTICData.h TTACTICDataDict.cxx TTACTICData.rootmap libNPTACTIC.dylib DEPENDS TTACTICData.h) +add_library(NPTACTIC SHARED TTACTICSpectra.cxx TTACTICData.cxx TTACTICPhysics.cxx TTACTICDataDict.cxx TTACTICPhysicsDict.cxx ) +target_link_libraries(NPTACTIC ${ROOT_LIBRARIES} NPCore) +install(FILES TTACTICData.h TTACTICPhysics.h TTACTICSpectra.h DESTINATION ${CMAKE_INCLUDE_OUTPUT_DIRECTORY}) + diff --git a/NPLib/Detectors/TACTIC/TTACTICData.cxx b/NPLib/Detectors/TACTIC/TTACTICData.cxx new file mode 100644 index 0000000000000000000000000000000000000000..11b67cc87c443714e88294df2ff341322db0321f --- /dev/null +++ b/NPLib/Detectors/TACTIC/TTACTICData.cxx @@ -0,0 +1,79 @@ +/***************************************************************************** + * Copyright (C) 2009-2020 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: Warren Lynch contact address: warren.lynch@york.ac.uk * + * * + * Creation Date : June 2020 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class hold TACTIC Raw data * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + * * + *****************************************************************************/ +#include "TTACTICData.h" + +#include <iostream> +#include <fstream> +#include <sstream> +#include <string> +using namespace std; + +ClassImp(TTACTICData) + + +////////////////////////////////////////////////////////////////////// +TTACTICData::TTACTICData() { +} + + + +////////////////////////////////////////////////////////////////////// +TTACTICData::~TTACTICData() { +} + + + +////////////////////////////////////////////////////////////////////// +void TTACTICData::Clear() { + // Energy + fTACTIC_E_DetectorNbr.clear(); + fTACTIC_Energy.clear(); + // Time + fTACTIC_T_DetectorNbr.clear(); + fTACTIC_Time.clear(); +} + + + +////////////////////////////////////////////////////////////////////// +void TTACTICData::Dump() const { + // This method is very useful for debuging and worth the dev. + cout << "XXXXXXXXXXXXXXXXXXXXXXXX New Event [TTACTICData::Dump()] XXXXXXXXXXXXXXXXX" << endl; + + // Energy + size_t mysize = fTACTIC_E_DetectorNbr.size(); + cout << "TACTIC_E_Mult: " << mysize << endl; + + for (size_t i = 0 ; i < mysize ; i++){ + cout << "DetNbr: " << fTACTIC_E_DetectorNbr[i] + << " Energy: " << fTACTIC_Energy[i]; + } + + // Time + mysize = fTACTIC_T_DetectorNbr.size(); + cout << "TACTIC_T_Mult: " << mysize << endl; + + for (size_t i = 0 ; i < mysize ; i++){ + cout << "DetNbr: " << fTACTIC_T_DetectorNbr[i] + << " Time: " << fTACTIC_Time[i]; + } +} diff --git a/NPLib/Detectors/TACTIC/TTACTICData.h b/NPLib/Detectors/TACTIC/TTACTICData.h new file mode 100644 index 0000000000000000000000000000000000000000..65e6388e243ecfc97fed2b2d46a0f055a48b9f06 --- /dev/null +++ b/NPLib/Detectors/TACTIC/TTACTICData.h @@ -0,0 +1,104 @@ +#ifndef __TACTICDATA__ +#define __TACTICDATA__ +/***************************************************************************** + * Copyright (C) 2009-2020 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: Warren Lynch contact address: warren.lynch@york.ac.uk * + * * + * Creation Date : June 2020 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class hold TACTIC Raw data * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + * * + *****************************************************************************/ + +// STL +#include <vector> +using namespace std; + +// ROOT +#include "TObject.h" + +class TTACTICData : public TObject { + ////////////////////////////////////////////////////////////// + // data members are hold into vectors in order + // to allow multiplicity treatment + private: + // Energy + vector<UShort_t> fTACTIC_E_DetectorNbr; + vector<Double_t> fTACTIC_Energy; + + // Time + vector<UShort_t> fTACTIC_T_DetectorNbr; + vector<Double_t> fTACTIC_Time; + + + ////////////////////////////////////////////////////////////// + // Constructor and destructor + public: + TTACTICData(); + ~TTACTICData(); + + + ////////////////////////////////////////////////////////////// + // 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){ + fTACTIC_E_DetectorNbr.push_back(DetNbr); + fTACTIC_Energy.push_back(Energy); + };//! + + // Time + inline void SetTime(const UShort_t& DetNbr,const Double_t& Time) { + fTACTIC_T_DetectorNbr.push_back(DetNbr); + fTACTIC_Time.push_back(Time); + };//! + + + ////////////////////// GETTERS //////////////////////// + // Energy + inline UShort_t GetMultEnergy() const + {return fTACTIC_E_DetectorNbr.size();} + inline UShort_t GetE_DetectorNbr(const unsigned int &i) const + {return fTACTIC_E_DetectorNbr[i];}//! + inline Double_t Get_Energy(const unsigned int &i) const + {return fTACTIC_Energy[i];}//! + + // Time + inline UShort_t GetMultTime() const + {return fTACTIC_T_DetectorNbr.size();} + inline UShort_t GetT_DetectorNbr(const unsigned int &i) const + {return fTACTIC_T_DetectorNbr[i];}//! + inline Double_t Get_Time(const unsigned int &i) const + {return fTACTIC_Time[i];}//! + + + ////////////////////////////////////////////////////////////// + // Required for ROOT dictionnary + ClassDef(TTACTICData,1) // TACTICData structure +}; + +#endif diff --git a/NPLib/Detectors/TACTIC/TTACTICPhysics.cxx b/NPLib/Detectors/TACTIC/TTACTICPhysics.cxx new file mode 100644 index 0000000000000000000000000000000000000000..033b2ba08478945695f133e2a1197ac02cbdde43 --- /dev/null +++ b/NPLib/Detectors/TACTIC/TTACTICPhysics.cxx @@ -0,0 +1,344 @@ +/***************************************************************************** + * Copyright (C) 2009-2020 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: Warren Lynch contact address: warren.lynch@york.ac.uk * + * * + * Creation Date : June 2020 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class hold TACTIC Treated data * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + * * + *****************************************************************************/ + +#include "TTACTICPhysics.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(TTACTICPhysics) + + +/////////////////////////////////////////////////////////////////////////// +TTACTICPhysics::TTACTICPhysics() + : m_EventData(new TTACTICData), + m_PreTreatedData(new TTACTICData), + 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 TTACTICPhysics::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 TTACTICPhysics::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 TTACTICPhysics::BuildSimplePhysicalEvent() { + BuildPhysicalEvent(); +} + + + +/////////////////////////////////////////////////////////////////////////// +void TTACTICPhysics::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 TTACTICPhysics::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("TACTIC/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("TACTIC/TIME"+NPL::itoa(m_EventData->GetT_DetectorNbr(i)),m_EventData->Get_Time(i)); + m_PreTreatedData->SetTime(m_EventData->GetT_DetectorNbr(i), Time); + } +} + + + +/////////////////////////////////////////////////////////////////////////// +void TTACTICPhysics::ReadAnalysisConfig() { + bool ReadingStatus = false; + + // path to file + string FileName = "./configs/ConfigTACTIC.dat"; + + // open analysis config file + ifstream AnalysisConfigFile; + AnalysisConfigFile.open(FileName.c_str()); + + if (!AnalysisConfigFile.is_open()) { + cout << " No ConfigTACTIC.dat found: Default parameter loaded for Analayis " << FileName << endl; + return; + } + cout << " Loading user parameter for Analysis from ConfigTACTIC.dat " << endl; + + // Save it in a TAsciiFile + TAsciiFile* asciiConfig = RootOutput::getInstance()->GetAsciiFileAnalysisConfig(); + asciiConfig->AppendLine("%%% ConfigTACTIC.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 = "ConfigTACTIC"; + 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 TTACTICPhysics::Clear() { + DetectorNumber.clear(); + Energy.clear(); + Time.clear(); +} + + + +/////////////////////////////////////////////////////////////////////////// +void TTACTICPhysics::ReadConfiguration(NPL::InputParser parser) { + vector<NPL::InputBlock*> blocks = parser.GetAllBlocksWithToken("TACTIC"); + 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 << "//// TACTIC " << 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 << "//// TACTIC " << 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 TTACTICPhysics::InitSpectra() { + m_Spectra = new TTACTICSpectra(m_NumberOfDetectors); +} + + + +/////////////////////////////////////////////////////////////////////////// +void TTACTICPhysics::FillSpectra() { + m_Spectra -> FillRawSpectra(m_EventData); + m_Spectra -> FillPreTreatedSpectra(m_PreTreatedData); + m_Spectra -> FillPhysicsSpectra(m_EventPhysics); +} + + + +/////////////////////////////////////////////////////////////////////////// +void TTACTICPhysics::CheckSpectra() { + m_Spectra->CheckSpectra(); +} + + + +/////////////////////////////////////////////////////////////////////////// +void TTACTICPhysics::ClearSpectra() { + // To be done +} + + + +/////////////////////////////////////////////////////////////////////////// +map< string , TH1*> TTACTICPhysics::GetSpectra() { + if(m_Spectra) + return m_Spectra->GetMapHisto(); + else{ + map< string , TH1*> empty; + return empty; + } +} + +/////////////////////////////////////////////////////////////////////////// +void TTACTICPhysics::WriteSpectra() { + m_Spectra->WriteSpectra(); +} + + + +/////////////////////////////////////////////////////////////////////////// +void TTACTICPhysics::AddParameterToCalibrationManager() { + CalibrationManager* Cal = CalibrationManager::getInstance(); + for (int i = 0; i < m_NumberOfDetectors; ++i) { + Cal->AddParameter("TACTIC", "D"+ NPL::itoa(i+1)+"_ENERGY","TACTIC_D"+ NPL::itoa(i+1)+"_ENERGY"); + Cal->AddParameter("TACTIC", "D"+ NPL::itoa(i+1)+"_TIME","TACTIC_D"+ NPL::itoa(i+1)+"_TIME"); + } +} + + + +/////////////////////////////////////////////////////////////////////////// +void TTACTICPhysics::InitializeRootInputRaw() { + TChain* inputChain = RootInput::getInstance()->GetChain(); + inputChain->SetBranchStatus("TACTIC", true ); + inputChain->SetBranchAddress("TACTIC", &m_EventData ); +} + + + +/////////////////////////////////////////////////////////////////////////// +void TTACTICPhysics::InitializeRootInputPhysics() { + TChain* inputChain = RootInput::getInstance()->GetChain(); + inputChain->SetBranchAddress("TACTIC", &m_EventPhysics); +} + + + +/////////////////////////////////////////////////////////////////////////// +void TTACTICPhysics::InitializeRootOutput() { + TTree* outputTree = RootOutput::getInstance()->GetTree(); + outputTree->Branch("TACTIC", "TTACTICPhysics", &m_EventPhysics); +} + + + +//////////////////////////////////////////////////////////////////////////////// +// Construct Method to be pass to the DetectorFactory // +//////////////////////////////////////////////////////////////////////////////// +NPL::VDetector* TTACTICPhysics::Construct() { + return (NPL::VDetector*) new TTACTICPhysics(); +} + + + +//////////////////////////////////////////////////////////////////////////////// +// Registering the construct method to the factory // +//////////////////////////////////////////////////////////////////////////////// +extern "C"{ +class proxy_TACTIC{ + public: + proxy_TACTIC(){ + NPL::DetectorFactory::getInstance()->AddToken("TACTIC","TACTIC"); + NPL::DetectorFactory::getInstance()->AddDetector("TACTIC",TTACTICPhysics::Construct); + } +}; + +proxy_TACTIC p_TACTIC; +} + diff --git a/NPLib/Detectors/TACTIC/TTACTICPhysics.h b/NPLib/Detectors/TACTIC/TTACTICPhysics.h new file mode 100644 index 0000000000000000000000000000000000000000..02d22e3d52c14a3f427976163c6191693426f7a1 --- /dev/null +++ b/NPLib/Detectors/TACTIC/TTACTICPhysics.h @@ -0,0 +1,180 @@ +#ifndef TTACTICPHYSICS_H +#define TTACTICPHYSICS_H +/***************************************************************************** + * Copyright (C) 2009-2020 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: Warren Lynch contact address: warren.lynch@york.ac.uk * + * * + * Creation Date : June 2020 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class hold TACTIC 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 "TTACTICData.h" +#include "TTACTICSpectra.h" +#include "NPCalibrationManager.h" +#include "NPVDetector.h" +#include "NPInputParser.h" +// forward declaration +class TTACTICSpectra; + + + +class TTACTICPhysics : public TObject, public NPL::VDetector { + ////////////////////////////////////////////////////////////// + // constructor and destructor + public: + TTACTICPhysics(); + ~TTACTICPhysics() {}; + + + ////////////////////////////////////////////////////////////// + // 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 TTACTICSpectra class + // instantiate the TTACTICSpectra 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 TACTIC 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 TTACTICData object to TTACTICPhysics. + // needed for online analysis for example + void SetRawDataPointer(TTACTICData* rawDataPointer) {m_EventData = rawDataPointer;} + + // objects are not written in the TTree + private: + TTACTICData* m_EventData; //! + TTACTICData* m_PreTreatedData; //! + TTACTICPhysics* m_EventPhysics; //! + + // getters for raw and pre-treated data object + public: + TTACTICData* GetRawData() const {return m_EventData;} + TTACTICData* 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: + TTACTICSpectra* m_Spectra; // ! + + // spectra getter + public: + map<string, TH1*> GetSpectra(); + + // Static constructor to be passed to the Detector Factory + public: + static NPL::VDetector* Construct(); + + ClassDef(TTACTICPhysics,1) // TACTICPhysics structure +}; +#endif diff --git a/NPLib/Detectors/TACTIC/TTACTICSpectra.cxx b/NPLib/Detectors/TACTIC/TTACTICSpectra.cxx new file mode 100644 index 0000000000000000000000000000000000000000..4642385cdadf380d9316d99729ad385f05664117 --- /dev/null +++ b/NPLib/Detectors/TACTIC/TTACTICSpectra.cxx @@ -0,0 +1,174 @@ +/***************************************************************************** + * Copyright (C) 2009-2020 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: Warren Lynch contact address: warren.lynch@york.ac.uk * + * * + * Creation Date : June 2020 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class hold TACTIC Spectra * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + * * + *****************************************************************************/ + +// class header +#include "TTACTICSpectra.h" + +// STL +#include <iostream> +#include <string> +using namespace std; + +// NPTool header +#include "NPOptionManager.h" + + + +//////////////////////////////////////////////////////////////////////////////// +TTACTICSpectra::TTACTICSpectra() + : fNumberOfDetectors(0) { + SetName("TACTIC"); +} + + + +//////////////////////////////////////////////////////////////////////////////// +TTACTICSpectra::TTACTICSpectra(unsigned int NumberOfDetectors) { + if(NPOptionManager::getInstance()->GetVerboseLevel()>0) + cout << "************************************************" << endl + << "TTACTICSpectra : Initalizing control spectra for " + << NumberOfDetectors << " Detectors" << endl + << "************************************************" << endl ; + SetName("TACTIC"); + fNumberOfDetectors = NumberOfDetectors; + + InitRawSpectra(); + InitPreTreatedSpectra(); + InitPhysicsSpectra(); +} + + + +//////////////////////////////////////////////////////////////////////////////// +TTACTICSpectra::~TTACTICSpectra() { +} + + + +//////////////////////////////////////////////////////////////////////////////// +void TTACTICSpectra::InitRawSpectra() { + static string name; + for (unsigned int i = 0; i < fNumberOfDetectors; i++) { // loop on number of detectors + // Energy + name = "TACTIC"+NPL::itoa(i+1)+"_ENERGY_RAW"; + AddHisto1D(name, name, 4096, 0, 16384, "TACTIC/RAW"); + // Time + name = "TACTIC"+NPL::itoa(i+1)+"_TIME_RAW"; + AddHisto1D(name, name, 4096, 0, 16384, "TACTIC/RAW"); + } // end loop on number of detectors +} + + + +//////////////////////////////////////////////////////////////////////////////// +void TTACTICSpectra::InitPreTreatedSpectra() { + static string name; + for (unsigned int i = 0; i < fNumberOfDetectors; i++) { // loop on number of detectors + // Energy + name = "TACTIC"+NPL::itoa(i+1)+"_ENERGY_CAL"; + AddHisto1D(name, name, 500, 0, 25, "TACTIC/CAL"); + // Time + name = "TACTIC"+NPL::itoa(i+1)+"_TIME_CAL"; + AddHisto1D(name, name, 500, 0, 25, "TACTIC/CAL"); + + + } // end loop on number of detectors +} + + + +//////////////////////////////////////////////////////////////////////////////// +void TTACTICSpectra::InitPhysicsSpectra() { + static string name; + // Kinematic Plot + name = "TACTIC_ENERGY_TIME"; + AddHisto2D(name, name, 500, 0, 500, 500, 0, 50, "TACTIC/PHY"); +} + + + +//////////////////////////////////////////////////////////////////////////////// +void TTACTICSpectra::FillRawSpectra(TTACTICData* RawData) { + static string name; + static string family; + + // Energy + unsigned int sizeE = RawData->GetMultEnergy(); + for (unsigned int i = 0; i < sizeE; i++) { + name = "TACTIC"+NPL::itoa(RawData->GetE_DetectorNbr(i))+"_ENERGY_RAW"; + family = "TACTIC/RAW"; + + FillSpectra(family,name,RawData->Get_Energy(i)); + } + + // Time + unsigned int sizeT = RawData->GetMultTime(); + for (unsigned int i = 0; i < sizeT; i++) { + name = "TACTIC"+NPL::itoa(RawData->GetT_DetectorNbr(i))+"_TIME_RAW"; + family = "TACTIC/RAW"; + + FillSpectra(family,name,RawData->Get_Time(i)); + } +} + + + +//////////////////////////////////////////////////////////////////////////////// +void TTACTICSpectra::FillPreTreatedSpectra(TTACTICData* PreTreatedData) { + static string name; + static string family; + + // Energy + unsigned int sizeE = PreTreatedData->GetMultEnergy(); + for (unsigned int i = 0; i < sizeE; i++) { + name = "TACTIC"+NPL::itoa(PreTreatedData->GetE_DetectorNbr(i))+"_ENERGY_CAL"; + family = "TACTIC/CAL"; + + FillSpectra(family,name,PreTreatedData->Get_Energy(i)); + } + + // Time + unsigned int sizeT = PreTreatedData->GetMultTime(); + for (unsigned int i = 0; i < sizeT; i++) { + name = "TACTIC"+NPL::itoa(PreTreatedData->GetT_DetectorNbr(i))+"_TIME_CAL"; + family = "TACTIC/CAL"; + + FillSpectra(family,name,PreTreatedData->Get_Time(i)); + } +} + + + +//////////////////////////////////////////////////////////////////////////////// +void TTACTICSpectra::FillPhysicsSpectra(TTACTICPhysics* Physics) { + static string name; + static string family; + family= "TACTIC/PHY"; + + // Energy vs time + unsigned int sizeE = Physics->Energy.size(); + for(unsigned int i = 0 ; i < sizeE ; i++){ + name = "TACTIC_ENERGY_TIME"; + FillSpectra(family,name,Physics->Energy[i],Physics->Time[i]); + } +} + diff --git a/NPLib/Detectors/TACTIC/TTACTICSpectra.h b/NPLib/Detectors/TACTIC/TTACTICSpectra.h new file mode 100644 index 0000000000000000000000000000000000000000..9eb2c79fe55d8d7c4331ef1149dedf4d3da1f3e7 --- /dev/null +++ b/NPLib/Detectors/TACTIC/TTACTICSpectra.h @@ -0,0 +1,62 @@ +#ifndef TTACTICSPECTRA_H +#define TTACTICSPECTRA_H +/***************************************************************************** + * Copyright (C) 2009-2020 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: Warren Lynch contact address: warren.lynch@york.ac.uk * + * * + * Creation Date : June 2020 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class hold TACTIC Spectra * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + * * + *****************************************************************************/ + +// NPLib headers +#include "NPVSpectra.h" +#include "TTACTICData.h" +#include "TTACTICPhysics.h" + +// Forward Declaration +class TTACTICPhysics; + + +class TTACTICSpectra : public VSpectra { + ////////////////////////////////////////////////////////////// + // constructor and destructor + public: + TTACTICSpectra(); + TTACTICSpectra(unsigned int NumberOfDetectors); + ~TTACTICSpectra(); + + ////////////////////////////////////////////////////////////// + // Initialization methods + private: + void InitRawSpectra(); + void InitPreTreatedSpectra(); + void InitPhysicsSpectra(); + + ////////////////////////////////////////////////////////////// + // Filling methods + public: + void FillRawSpectra(TTACTICData*); + void FillPreTreatedSpectra(TTACTICData*); + void FillPhysicsSpectra(TTACTICPhysics*); + + ////////////////////////////////////////////////////////////// + // Detector parameters + private: + unsigned int fNumberOfDetectors; +}; + +#endif diff --git a/NPLib/Physics/NPBeam.cxx b/NPLib/Physics/NPBeam.cxx index d9487db7aaf14d5c7e0b7b9dcd77498aecf55d93..e7644c7e4076621954b17203ce309dcb608e451a 100644 --- a/NPLib/Physics/NPBeam.cxx +++ b/NPLib/Physics/NPBeam.cxx @@ -50,6 +50,7 @@ using namespace NPL; //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... Beam::Beam(){ + fExcitationEnergy = 0; fEnergy = 0; fSigmaEnergy = -1 ; fMeanX = 0 ; diff --git a/NPLib/Physics/NPFunction.cxx b/NPLib/Physics/NPFunction.cxx index 053fd0f7d2381bc121912bd8019ebd6327c32657..9de2b666211aa8facae9ba279fafad1734c3437d 100644 --- a/NPLib/Physics/NPFunction.cxx +++ b/NPLib/Physics/NPFunction.cxx @@ -279,7 +279,7 @@ namespace NPL{ //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... - string ChangeNameToG4Standard(string OriginalName){ + string ChangeNameToG4Standard(string OriginalName,bool excited){ string NumberOfMass ; string Nucleid; @@ -354,6 +354,8 @@ namespace NPL{ // Special case for light particles string FinalName=Nucleid+NumberOfMass; + + if(!excited){ if (FinalName=="H1") FinalName="proton"; else if (FinalName=="H2") FinalName="deuteron"; else if (FinalName=="H3") FinalName="triton"; @@ -363,6 +365,7 @@ namespace NPL{ else if (FinalName=="t") FinalName="triton"; else if (FinalName=="a") FinalName="alpha"; else if (FinalName=="n") FinalName="neutron"; + } return(FinalName); } @@ -440,8 +443,8 @@ namespace NPL{ else if (character.str()=="z") Nucleid+="z"; } - // Special case for light particles string FinalName=NumberOfMass+Nucleid; + // Special case for light particles if (FinalName=="H1") FinalName="proton"; else if (FinalName=="H2") FinalName="deuteron"; else if (FinalName=="H3") FinalName="triton"; diff --git a/NPLib/Physics/NPFunction.h b/NPLib/Physics/NPFunction.h index b6373860d8c04d2559877846e4b025ac0fbc1099..8150a644e5c321bb6c80aa2eee3bc893d993b851 100644 --- a/NPLib/Physics/NPFunction.h +++ b/NPLib/Physics/NPFunction.h @@ -58,7 +58,7 @@ namespace NPL{ void RandomGaussian2D(double MeanX, double MeanY, double SigmaX, double SigmaY, double &X, double &Y); // Change nucleus name from G4 standard to Physics standard (11Li vs Li11) - string ChangeNameToG4Standard(string name); + string ChangeNameToG4Standard(string name,bool excited=false); string ChangeNameFromG4Standard(string name); // Hyperbolic shape generator for cryogenic target deformation diff --git a/NPLib/Physics/NPQFS.cxx b/NPLib/Physics/NPQFS.cxx index 108d319c9c4bb3bb41100e8a1baf71934662dd38..0eca56b43739e4fa15791704956dd0f1bef61013 100644 --- a/NPLib/Physics/NPQFS.cxx +++ b/NPLib/Physics/NPQFS.cxx @@ -17,11 +17,11 @@ * or a nucleon is removed from a projectile by interaction with a target * * nucleon (proton target in general) * * * - * First step (dissociation): A -> B + c * - * Second step (scattering) : c + T -> 1 + 2 * + * First step (dissociation): A -> B + a * + * Second step (scattering) : a + T -> 1 + 2 * * Labeling is: * * * - * A --> T ==> B + (c -> T) => B + 1 + 2 * + * A --> T ==> B + (a -> T) => B + 1 + 2 * * * * where: * * + A is the beam nucleus * @@ -29,7 +29,7 @@ * * * + B is the residual fragment (beam-like) * * + 1 is the scattered target nucleon (former T) * - * + 2 is the knocked-out cluster/nucleon (noted c) in the intermediate * + * + 2 is the knocked-out cluster/nucleon (noted a) in the intermediate * *---------------------------------------------------------------------------* * Comment: * * + Adapted from original event generator from V. Panin (R3B collab) * @@ -83,6 +83,9 @@ QFS::QFS(){ fTheta2VsTheta1 = 0; fPhi2VsPhi1 = 0; + fPerpMomentumHist = NULL; + fParMomentumHist = NULL; + } //////////////////////////////////////////////////////////////////////////////// @@ -153,6 +156,16 @@ void QFS::ReadConfigurationFile(NPL::InputParser parser){ fshoot1 = blocks[i]->GetInt("ShootLight"); fshoot2 = blocks[i]->GetInt("ShootLight"); } + if(blocks[i]->HasToken("PerpMomentumPath")){ + vector<string> file_perp = blocks[i]->GetVectorString("PerpMomentumPath"); + TH1F* Perptemp = Read1DProfile(file_perp[0], file_perp[1]); + SetPerpMomentumHist(Perptemp); + } + if(blocks[i]->HasToken("ParMomentumPath")){ + vector<string> file_par = blocks[i]->GetVectorString("ParMomentumPath"); + TH1F* Partemp = Read1DProfile(file_par[0], file_par[1]); + SetParMomentumHist(Partemp); + } } cout << "\033[0m" ; @@ -202,7 +215,7 @@ void QFS::CalculateVariables(){ //cout<<"---- COMPUTE ------"<<endl; // cout<<"--CM--"<<endl; - mA = fNucleiA.Mass(); // Beam mass in MeV + mA = fNucleiA.Mass(); // Beam mass in MeV mT = fNucleiT.Mass(); // Target mass in MeV mB = fNucleiB.Mass(); // Heavy residual mass in MeV m1 = mT; // scattered target nucleon (same mass); @@ -214,17 +227,13 @@ void QFS::CalculateVariables(){ double EA = sqrt(mA*mA + PA*PA); // Beam total energy fEnergyImpulsionLab_A = TLorentzVector(0.,0.,PA,EA); - //Internal momentum of removed cluster/nucleon - //gRandom->SetSeed(0); - //Pa.SetX(gRandom->Gaus(0.,fMomentumSigma)); - //Pa.SetY(gRandom->Gaus(0.,fMomentumSigma)); - //Pa.SetZ(gRandom->Gaus(0.,fMomentumSigma)); - Pa.SetX(fInternalMomentum.X()); - Pa.SetY(fInternalMomentum.Y()); - Pa.SetZ(fInternalMomentum.Z()); - - //Internal momentum of heavy recoil after removal - PB.SetXYZ( (-Pa.X()) , (-Pa.Y()) , (-Pa.Z()) ); + // Internal momentum of removed cluster/nucleon (Pa) and recoil (PB) + // here fInternalMomentum contains PB (recoil fragment momentum) + // readout from the input file (theoretical) + PB.SetX(fInternalMomentum.X()); + PB.SetY(fInternalMomentum.Y()); + PB.SetZ(fInternalMomentum.Z()); + Pa.SetXYZ( (-PB.X()) , (-PB.Y()) , (-PB.Z()) ); // Off-shell mass of the bound nucleon from E conservation // in virtual dissociation of A -> B + a @@ -298,7 +307,7 @@ void QFS::KineRelativistic(double& ThetaLab1, double& PhiLab1, double& KineticEn pCM_2*sin(thetaCM_2)*sin(phiCM_2), pCM_2*cos(thetaCM_2), ECM_2); - + fEnergyImpulsionCM_1 = fTotalEnergyImpulsionCM - fEnergyImpulsionCM_2; //-- Boost in the direction of the moving cluster "a" --// @@ -312,7 +321,7 @@ void QFS::KineRelativistic(double& ThetaLab1, double& PhiLab1, double& KineticEn TVector3 direction = Pa_lab.Unit(); fEnergyImpulsionLab_1.RotateUz(direction); fEnergyImpulsionLab_2.RotateUz(direction); - +/* // Angle in the Lab frame ThetaLab1 = fEnergyImpulsionLab_1.Angle(fEnergyImpulsionLab_A.Vect()); //ThetaLab1 = fEnergyImpulsionLab_1.Angle(z_axis); @@ -327,11 +336,16 @@ void QFS::KineRelativistic(double& ThetaLab1, double& PhiLab1, double& KineticEn if (fabs(PhiLab1) < 1e-6) PhiLab1 = 0; PhiLab2 = M_PI + fEnergyImpulsionLab_2.Vect().Phi(); if (fabs(PhiLab2) < 1e-6) PhiLab2 = 0; +*/ + + ThetaLab1 = fEnergyImpulsionLab_1.Angle(fEnergyImpulsionLab_A.Vect()); + ThetaLab2 = fEnergyImpulsionLab_2.Angle(fEnergyImpulsionLab_A.Vect()); + PhiLab1 = fEnergyImpulsionLab_1.Vect().Phi(); + PhiLab2 = fEnergyImpulsionLab_2.Vect().Phi(); // Kinetic Energy in the lab frame KineticEnergyLab1 = fEnergyImpulsionLab_1.E() - m1; KineticEnergyLab2 = fEnergyImpulsionLab_2.E() - m2; - // test for total energy conversion //if (fabs(fTotalEnergyImpulsionLab.E() - (fEnergyImpulsionLab_1.E()+fEnergyImpulsionLab_2.E())) > 1e-6) // cout << "Problem for energy conservation" << endl; @@ -400,10 +414,39 @@ void QFS::Dump(){ } //////////////////////////////////////////////////////////////////////////////////////////// -double QFS::ShootRandomThetaCM(){ - // TO DO // - double theta =0; - return theta; +TVector3 QFS::ShootInternalMomentum(){ + + //Shoot a momentum (vector) for the internal cluster in the beam-at-rest frame + // (1) if only a width is provided: shoot in 3 independant Gaussian + // (2) if input histos are provided: use them instead of option (1) + // Remark : if both width and input histos are provided only histos are considered + + TVector3 momentum = {0,0,0}; + double PerpMomentum =0; + double ParMomentum =0; + double angle_tmp =0; + + momentum.SetX(gRandom->Gaus(0.,fMomentumSigma)); + momentum.SetY(gRandom->Gaus(0.,fMomentumSigma)); + momentum.SetZ(gRandom->Gaus(0.,fMomentumSigma)); + + if(fPerpMomentumHist){ + PerpMomentum=fPerpMomentumHist->GetRandom(); + angle_tmp = gRandom->Rndm()*2*M_PI; + momentum.SetX(PerpMomentum * TMath::Cos(angle_tmp)); + momentum.SetY(PerpMomentum * TMath::Sin(angle_tmp)); + } + if(fParMomentumHist){ + ParMomentum=fParMomentumHist->GetRandom(); + momentum.SetZ(ParMomentum); + } + + //cout << " Shooting Random Momentum: " << endl; + //cout<<"Px:"<<momentum.X() << endl; + //cout<<"Py:"<<momentum.Y() << endl; + //cout<<"Pz:"<<momentum.Z() << endl; + SetInternalMomentum(momentum); + return momentum; } //////////////////////////////////////////////////////////////////////////////////////////// diff --git a/NPLib/Physics/NPQFS.h b/NPLib/Physics/NPQFS.h index fde81d853e41ddecd681fb4d88b03697627ceebc..0016793dde93bf66fcd5f72c8b332f444be2b78d 100644 --- a/NPLib/Physics/NPQFS.h +++ b/NPLib/Physics/NPQFS.h @@ -81,6 +81,8 @@ namespace NPL{ double fExcitationB; // Excitation energy in MeV of beam-like ejectile double fMomentumSigma; // Width of the momentum distribution (sigma) TVector3 fInternalMomentum; // Internal momentum of the removed cluster + TH1F* fPerpMomentumHist; // Perpendicular momentum distribution in beam at rest frame + TH1F* fParMomentumHist; // Parallel momentum distribution in beam at rest frame double fisotropic; TGraph* fTheta2VsTheta1; @@ -98,7 +100,7 @@ namespace NPL{ void CalculateVariables(); void TestR3B(); void KineRelativistic(double &ThetaLab1, double &PhiLab1, double &KineticEnergyLab1, double &ThetaLab2, double &PhiLab2, double &KineticEnergyLab2); - double ShootRandomThetaCM(); + TVector3 ShootInternalMomentum(); bool IsAllowed(); void Dump(); @@ -165,6 +167,10 @@ namespace NPL{ void SetPhiCM(const double& angle) {fPhiCM = angle;} void SetInternalMomentum(const TVector3& mom) {fInternalMomentum = mom;} void SetMomentumSigma(const double& sigma) {fMomentumSigma = sigma;} + void SetPerpMomentumHist (TH1F* PerpMomentumHist) + {delete fPerpMomentumHist; fPerpMomentumHist = PerpMomentumHist;} + void SetParMomentumHist (TH1F* ParMomentumHist) + {delete fParMomentumHist; fParMomentumHist = ParMomentumHist;} //GETTERS Nucleus* GetNucleusA() {return &fNucleiA;} diff --git a/NPLib/Physics/TReactionConditions.cxx b/NPLib/Physics/TReactionConditions.cxx index 0a2fa85cce65c6f9943fe709d5af60a67fa410b4..f4400ba39319a904ee1f13991c0268ba2a850033 100644 --- a/NPLib/Physics/TReactionConditions.cxx +++ b/NPLib/Physics/TReactionConditions.cxx @@ -38,18 +38,18 @@ TReactionConditions::~TReactionConditions(){ void TReactionConditions::Clear(){ // Beam beam parameter fRC_Beam_Particle_Name=""; - fRC_Beam_Emittance_ThetaX = -1; - fRC_Beam_Emittance_PhiY = -1; - fRC_Beam_Emittance_Theta = -1; - fRC_Beam_Emittance_Phi = -1; - fRC_Beam_Reaction_Energy = -1; + fRC_Beam_Emittance_ThetaX = -1000; + fRC_Beam_Emittance_PhiY = -1000; + fRC_Beam_Emittance_Theta = -1000; + fRC_Beam_Emittance_Phi = -1000; + fRC_Beam_Reaction_Energy = -1000; - fRC_Vertex_Position_X = -1; - fRC_Vertex_Position_Y = -1; - fRC_Vertex_Position_Z = -1; + fRC_Vertex_Position_X = -1000; + fRC_Vertex_Position_Y = -1000; + fRC_Vertex_Position_Z = -1000; - fRC_ThetaCM = -1; - fRC_Internal_Momentum = {-1, -1, -1}; + fRC_ThetaCM = -1000; + fRC_Internal_Momentum = {-1000, -1000, -1000}; // emmitted particles fRC_Particle_Name.clear(); @@ -59,6 +59,7 @@ void TReactionConditions::Clear(){ fRC_Momentum_Direction_X.clear(); fRC_Momentum_Direction_Y.clear(); fRC_Momentum_Direction_Z.clear(); + fRC_Momentum.clear(); } //////////////////////////////////////////////////////////////////////////////// void TReactionConditions::Dump() const{ @@ -114,4 +115,5 @@ TVector3 TReactionConditions::GetParticleDirection (const int i) const { fRC_Momentum_Direction_Y[i], fRC_Momentum_Direction_Z[i]); } +//////////////////////////////////////////////////////////////////////////////// diff --git a/NPLib/Physics/TReactionConditions.h b/NPLib/Physics/TReactionConditions.h index 307af4ad2143c808e047966cd0ec377c635601c8..93c70537e1b7b1fb4dab4a4ac2717a231cbb6187 100644 --- a/NPLib/Physics/TReactionConditions.h +++ b/NPLib/Physics/TReactionConditions.h @@ -68,6 +68,7 @@ private: vector<double> fRC_Momentum_Direction_X; vector<double> fRC_Momentum_Direction_Y; vector<double> fRC_Momentum_Direction_Z; + vector<TVector3> fRC_Momentum; public: @@ -103,6 +104,12 @@ public: void SetMomentumDirectionX (const double & Momentum_Direction_X) {fRC_Momentum_Direction_X.push_back(Momentum_Direction_X);}//! void SetMomentumDirectionY (const double & Momentum_Direction_Y) {fRC_Momentum_Direction_Y.push_back(Momentum_Direction_Y);}//! void SetMomentumDirectionZ (const double & Momentum_Direction_Z) {fRC_Momentum_Direction_Z.push_back(Momentum_Direction_Z);}//! + void SetMomentum (const TVector3 & Momentum) { + Momentum.Unit(); + SetMomentumDirectionX(Momentum.X()); + SetMomentumDirectionY(Momentum.Y()); + SetMomentumDirectionZ(Momentum.Z()); + }//! ///////////////////// GETTERS //////////////////////// // Beam parameter @@ -131,6 +138,7 @@ public: double GetMomentumDirectionX (const int &i) const {return fRC_Momentum_Direction_X[i];}//! double GetMomentumDirectionY (const int &i) const {return fRC_Momentum_Direction_Y[i];}//! double GetMomentumDirectionZ (const int &i) const {return fRC_Momentum_Direction_Z[i];}//! + TVector3 GetParticleMomentum (const int &i) const {return TVector3(fRC_Momentum_Direction_X[i],fRC_Momentum_Direction_Y[i],fRC_Momentum_Direction_Z[i]).Unit();}//! TVector3 GetBeamDirection () const ; TVector3 GetParticleDirection (const int i) const ; diff --git a/NPLib/TrackReconstruction/CMakeLists.txt b/NPLib/TrackReconstruction/CMakeLists.txt index 1b61b7ecb9ed0fedb0e7c677ac93a740734e158b..7fbdc6a68095ffa765c31ea83dc992c0f5143f6c 100644 --- a/NPLib/TrackReconstruction/CMakeLists.txt +++ b/NPLib/TrackReconstruction/CMakeLists.txt @@ -7,4 +7,4 @@ add_custom_command(OUTPUT TrackingDict.cxx COMMAND ${CMAKE_BINARY_DIR}/scripts/b add_library(NPTrackReconstruction SHARED NPRansac.cxx NPCluster.cxx NPTrack.cxx Tracking.cxx NPRansacDict.cxx NPClusterDict.cxx TrackingDict.cxx) target_link_libraries(NPTrackReconstruction ${ROOT_LIBRARIES} NPCore) -install(FILES NPRansac.h NPCluster.h NPTrack.h Tracking.h DESTINATION ${CMAKE_INCLUDE_OUTPUT_DIRECTORY}) +install(FILES NPRansac.h NPCluster.h NPTrack.h Tracking.h NPTrackingUtility.h DESTINATION ${CMAKE_INCLUDE_OUTPUT_DIRECTORY}) diff --git a/NPLib/TrackReconstruction/NPTrackingUtility.h b/NPLib/TrackReconstruction/NPTrackingUtility.h new file mode 100644 index 0000000000000000000000000000000000000000..ee7c30502399c3bbae7ac174869277243d923457 --- /dev/null +++ b/NPLib/TrackReconstruction/NPTrackingUtility.h @@ -0,0 +1,54 @@ +#ifndef NPUTILITY_H +#define NPUTILITY_H +/***************************************************************************** + * 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 : July 2020 * + *---------------------------------------------------------------------------* + * Decription: * + * This class deal with finding all the track event by event * + *****************************************************************************/ + +namespace NPL{ + ////////////////////////////////////////////////////////////////////////////// + // return the minimum distance between v and w defined respectively by points + // v1,v2 and w1 w1 + // Also compute the best crossing position BestPosition, i.e. average position + // at the minimum distance. + double MinimumDistanceTwoLines(const TVector3& v1,const TVector3& v2, const TVector3& w1, const TVector3& w2, TVector3& BestPosition, TVector3& delta){ + TVector3 v = v2-v1; + TVector3 w = w2-w1; + // Finding best position + TVector3 e = v1-w1; + double A = -(v.Mag2()*w.Mag2()-(v.Dot(w)*v.Dot(w))); + double s = (-v.Mag2()*(w.Dot(e))+(v.Dot(e))*(w.Dot(v)))/A; + double t = (w.Mag2()*(v.Dot(e))-(w.Dot(e)*w.Dot(v)))/A; + double d = sqrt((e+v*t-w*s).Mag2()); + + BestPosition = 0.5*(v1+t*v+w1+s*w); + delta = (v1+t*v-w1-s*w); + return d; + } + + ////////////////////////////////////////////////////////////////////////////// + // return the minimum distance between the line defines by v1,v2 and the point + // in space x + // demo is here: https://mathworld.wolfram.com/Point-LineDistance3-Dimensional.html + double MinimumDistancePointLine(const TVector3& v1, const TVector3& v2, const TVector3& x){ + TVector3 w1 = x-v1; + TVector3 w2 = x-v2; + TVector3 w = w1.Cross(w2); + return w.Mag()/(v2-v1).Mag(); + } +} + + +#endif diff --git a/NPLib/scripts/NPToolLogon.C b/NPLib/scripts/NPToolLogon.C index d3bdf5e8d522dce0bdab1163475232fe6e6386c3..f33ea030d0d6fb7846185f486c88ade64b4ae402 100644 --- a/NPLib/scripts/NPToolLogon.C +++ b/NPLib/scripts/NPToolLogon.C @@ -36,6 +36,14 @@ using namespace std; #include"TRandom.h" #include"TRandom2.h" +bool contains(std::string path,std::string search){ + if(path.find(search)!=std::string::npos) + return true; + else + return false; + } + +///////////////////////////////////////////////////// void NPToolLogon(){ #ifdef __APPLE__ @@ -74,8 +82,8 @@ void NPToolLogon(){ if(!check){ // Add shared libraries - TString libpath = Form("%s/NPLib/lib", path.c_str()); - TSystemDirectory libdir("libdir", libpath); + std::string libpath = Form("%s/NPLib/lib", path.c_str()); + TSystemDirectory libdir("libdir", libpath.c_str()); TList* listfile = libdir.GetListOfFiles(); // Since the list is ordered alphabetically and that the @@ -83,7 +91,8 @@ void NPToolLogon(){ // lib*Physics.dylib libraries, it is then loaded manually // first. // Test if the lib directory is empty or not - if (listfile->GetEntries() > 2) gSystem->Load(libpath+"/libNPCore"+Lib_Extension); + std::string load_path = libpath+"/libNPCore"+Lib_Extension; + if (listfile->GetEntries() > 2) gSystem->Load(load_path.c_str()); gSystem->Load("libPhysics.so"); // Needed by Must2 and Sharc gSystem->Load("libHist.so"); // Needed by TSpectra Class @@ -91,30 +100,30 @@ void NPToolLogon(){ // Loop on Data libraries Int_t i = 0; while (listfile->At(i)) { - TString libname = listfile->At(i++)->GetName(); - if (libname.Contains(Lib_Extension) && libname.Contains("Data") && !libname.Contains("libVDetector"+Lib_Extension)) { - TString lib = libpath + "/" + libname; - gSystem->Load(lib); + std::string libname = listfile->At(i++)->GetName(); + if (contains(libname,Lib_Extension) && contains(libname,"Data") && !contains(libname,"libVDetector"+Lib_Extension)) { + std::string lib = libpath + "/" + libname; + gSystem->Load(lib.c_str()); } } // Loop on Physics Library i = 0; while (listfile->At(i)) { - TString libname = listfile->At(i++)->GetName(); - if (libname.Contains(Lib_Extension) && libname.Contains("Physics") &&!libname.Contains("libVDetector"+Lib_Extension)) { - TString lib = libpath + "/" + libname; - gSystem->Load(lib); + std::string libname = listfile->At(i++)->GetName(); + if (contains(libname,Lib_Extension) && contains(libname,"Physics") &&!contains(libname,"libVDetector"+Lib_Extension)) { + std::string lib = libpath + "/" + libname; + gSystem->Load(lib.c_str()); } } // Loop on the Reset of the Library i = 0; while (listfile->At(i)) { - TString libname = listfile->At(i++)->GetName(); - if (libname.Contains(Lib_Extension) && !libname.Contains("Physics") && !libname.Contains("Data") &&!libname.Contains("libVDetector"+Lib_Extension)) { - TString lib = libpath + "/" + libname; - gSystem->Load(lib); + std::string libname = listfile->At(i++)->GetName(); + if (contains(libname,Lib_Extension) && !contains(libname,"Physics") && !contains(libname,"Data") &&!contains(libname,"libVDetector"+Lib_Extension)) { + std::string lib = libpath + "/" + libname; + gSystem->Load(lib.c_str()); } } @@ -125,3 +134,5 @@ void NPToolLogon(){ gSystem->cd(currentpath.c_str()); } } + + diff --git a/NPSimulation/CMakeLists.txt b/NPSimulation/CMakeLists.txt index e0e1e932675146237b5b2488d0d42d0f60411384..22745153d394778bb24de6d8f1354d9bfb674dc4 100644 --- a/NPSimulation/CMakeLists.txt +++ b/NPSimulation/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.8) +cmake_minimum_required (VERSION 3.0) include(CheckCXXCompilerFlag) # Setting the policy to match Cmake version @@ -60,7 +60,6 @@ if(Geant4_gdml_FOUND) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DNPS_GDML") endif() - # set the Geant4 version info set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -DNPS_GEANT4_VERSION_MAJOR=${NPS_GEANT4_VERSION_MAJOR}") diff --git a/NPSimulation/Core/MaterialManager.cc b/NPSimulation/Core/MaterialManager.cc index 06e15382856494685feecdcdaad90908b6875f19..e111e5f16c7d0f03596d55eaa27f13830fa5109d 100644 --- a/NPSimulation/Core/MaterialManager.cc +++ b/NPSimulation/Core/MaterialManager.cc @@ -956,10 +956,7 @@ G4Material* MaterialManager::GetMaterialFromLibrary(string Name, = {35. * cm, 35. * cm, 35. * cm, 35. * cm, 35. * cm, 35. * cm, 35. * cm, 35. * cm, 35. * cm, 35. * cm, 35. * cm, 35. * cm, 35. * cm, 35. * cm, 35. * cm}; - /*G4double THICK_ABSL[NUMENTRIES] = - {0.01*mm,0.01*mm,0.01*mm,0.01*mm,0.01*mm,0.01*mm,0.01*mm,0.01*mm, - 0.01*mm,0.01*mm,0.01*mm,0.01*mm,0.01*mm,0.01*mm,0.01*mm};*/ - + G4MaterialPropertiesTable* myMPT2 = new G4MaterialPropertiesTable(); myMPT2->AddProperty("RINDEX", PMMA_PP, PMMA_RIND, NUMENTRIES); myMPT2->AddProperty("ABSLENGTH", PMMA_PP, PMMA_ABSL, NUMENTRIES); @@ -1018,11 +1015,18 @@ G4Material* MaterialManager::GetMaterialFromLibrary(string Name, } else { - G4cout << "ERROR: Material requested \"" << Name - << "\" is not available in the Material Library, trying with NIST" - << G4endl; + cout << "INFO: trying to get " << Name << " material from NIST" << endl; G4NistManager* man = G4NistManager::Instance(); - return man->FindOrBuildMaterial(Name.c_str()); + G4Material* material = man->FindOrBuildMaterial(Name.c_str()); + m_Material[Name] = material; + material->SetName("NPS_"+material->GetName()); + if(!material){ + cout << "ERROR: Material requested \"" << Name + << "\" is not available in the nptool material library or NIST" + << endl; + exit(1); + } + return material; } } @@ -1153,16 +1157,6 @@ G4Material* MaterialManager::GetGasFromLibrary(string Name, double Pressure, dou return material; } - /* if(Name == "mixMINOS"){ */ - /* density = (2*2.0140/Vm)*mg/cm3; */ - /* G4Material* material = new G4Material("NPS_"+newName,density,1,kStateGas,Temperature,Pressure); */ - /* material->AddElement(GetElementFromLibrary("D"), 2); */ - /* //material->AddElement(GetElementFromLibrary("D"), 1); */ - /* m_Material[newName]=material; */ - /* return material; */ - /* } */ - - else{ exit(1); } @@ -1322,7 +1316,7 @@ void MaterialManager::WriteCrossSectionTable(std::set<string> Particle, G4double //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... void MaterialManager::CreateSampleVolumes(G4LogicalVolume* world_log) { - // Crate a micrometer big cube for each material + // Create a micrometer size cube for each material G4double SampleSize = 1 * um; G4double WorldSize = 10.0 * m; G4Box* sample_box diff --git a/NPSimulation/Core/RunAction.cc b/NPSimulation/Core/RunAction.cc index 16289ab7205602cccac24e1ad58c033c98ac843f..a3a503e00f645f7c1815f708a40a676ee75553b1 100644 --- a/NPSimulation/Core/RunAction.cc +++ b/NPSimulation/Core/RunAction.cc @@ -69,10 +69,10 @@ void RunAction::EndOfRunAction(const G4Run* aRun){ for(unsigned int e = 0 ; e < sizeE ; e++){ TrajectoryVector* traj = (*events)[e]->GetTrajectoryContainer()->GetVector(); unsigned int size = traj->size(); + for(unsigned int i = 0 ; i < size ; i++) Particles.insert( (*traj)[i]->GetParticleName()); } - MaterialManager::getInstance()->WriteDEDXTable(Particles,0,10*GeV); MaterialManager::getInstance()->WriteCrossSectionTable(Particles,0,20*MeV); } diff --git a/NPSimulation/Core/Target.cc b/NPSimulation/Core/Target.cc index ab785a372e6c0c2259f32a6c3a68cd9e51252772..e743109de5861b91d1852c39275c18e7c6a04218 100644 --- a/NPSimulation/Core/Target.cc +++ b/NPSimulation/Core/Target.cc @@ -17,14 +17,7 @@ * * *---------------------------------------------------------------------------* * Comment: * - * Some improvment need to be done in material dealing * * * - * + 16/09/2009: Add support for positioning the target with an angle with * - * respect to the beam (N. de Sereville) * - * + 16/09/2009: Add CH2 material for targets (N. de Sereville) * - * + 06/11/2009: Add new Token m_TargetNbLayers defining the number of * - * steps used to slow down the beam in the target * - * (N. de Sereville) * * * *****************************************************************************/ // C++ header @@ -74,7 +67,7 @@ Target::Target(){ m_TargetAngle = 0 ; m_TargetRadius = 0 ; m_TargetDensity = 0 ; - m_TargetNbLayers = 5 ; // Number of steps by default + m_TargetNbSlices = 100. ; // Number of sslices/steps by default m_TargetBackingThickness = 0 ; m_ReactionRegion=NULL; @@ -144,8 +137,8 @@ void Target::ReadConfiguration(NPL::InputParser parser){ exit(1); } - if(starget[0]->HasToken("NBLAYERS")) - m_TargetNbLayers = starget[0]->GetInt("NBLAYERS"); + if(starget[0]->HasToken("NbSlices")) + m_TargetNbSlices = starget[0]->GetInt("NbSlices"); if(starget[0]->HasToken("BackingMaterial")&& starget[0]->HasToken("BackingThickness")){ m_TargetBackingMaterial=GetMaterialFromLibrary(starget[0]->GetString("BackingMaterial")); @@ -213,8 +206,8 @@ void Target::ReadConfiguration(NPL::InputParser parser){ exit(1); } - if(ctarget[0]->HasToken("NBLAYERS")) - m_TargetNbLayers = ctarget[0]->GetInt("NBLAYERS"); + if(ctarget[0]->HasToken("NbSlices")) + m_TargetNbSlices = ctarget[0]->GetInt("NbSlices"); } else{ @@ -458,7 +451,7 @@ void Target::ConstructDetector(G4LogicalVolume* world){ void Target::SetReactionRegion(){ m_ReactionRegion = G4RegionStore::GetInstance()->FindOrCreateRegion("NPSimulationProcess"); m_ReactionRegion->AddRootLogicalVolume(m_TargetLogic); - m_ReactionRegion->SetUserLimits(new G4UserLimits(m_TargetThickness/10.)); + m_ReactionRegion->SetUserLimits(new G4UserLimits(m_TargetThickness/m_TargetNbSlices)); G4FastSimulationManager* mng = m_ReactionRegion->GetFastSimulationManager(); unsigned int size = m_ReactionModel.size(); @@ -468,7 +461,7 @@ void Target::SetReactionRegion(){ m_ReactionModel.clear(); G4VFastSimulationModel* fsm; fsm = new NPS::BeamReaction("BeamReaction",m_ReactionRegion); - ((NPS::BeamReaction*) fsm)->SetStepSize(m_TargetThickness/10.); + ((NPS::BeamReaction*) fsm)->SetStepSize(m_TargetThickness/m_TargetNbSlices); m_ReactionModel.push_back(fsm); fsm = new NPS::Decay("Decay",m_ReactionRegion); m_ReactionModel.push_back(fsm); @@ -486,73 +479,6 @@ void Target::InitializeRootOutput() void Target::ReadSensitive(const G4Event*) {} -//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... -// Return the slow down beam energy after interaction at ZInteraction with initial beam energy before target IncidentEnergy -G4double Target::SlowDownBeam(G4ParticleDefinition* Beam, - G4double IncidentEnergy, - G4double ZInteraction, - G4double IncidentTheta){ - - if(Beam->GetParticleName()=="neutron"){ - return IncidentEnergy; - } - - if((0.5*m_TargetThickness+ZInteraction)<0){ - cout<< "Something is wrong with the Z coordinate of the interaction position"<<endl; - cout<< "Check the value of Z(interaction) " << ZInteraction << endl; - } - - G4double ThicknessBeforeInteraction = - (0.5*m_TargetThickness + ZInteraction) / cos(m_TargetAngle); - - G4double dedx,de; - static G4EmCalculator emCalculator; - - if(m_TargetType){ - if(m_TargetThickness!=0){ - for (G4int i = 0; i < m_TargetNbLayers; i++){ - dedx = emCalculator.ComputeTotalDEDX(IncidentEnergy, Beam, m_TargetMaterial); - de = dedx * ThicknessBeforeInteraction / m_TargetNbLayers; - IncidentEnergy -= de; - if(IncidentEnergy<0){ - IncidentEnergy = 0; - break; - } - } - } - } - - else{ - // Windows - if(m_FrontThickness!=0) - for (G4int i = 0; i < m_TargetNbLayers; i++){ - dedx = emCalculator.ComputeTotalDEDX(IncidentEnergy, Beam, m_FrontMaterial); - de = dedx * m_FrontThickness / (cos(IncidentTheta)* m_TargetNbLayers); - IncidentEnergy -= de; - if(IncidentEnergy<0){ - IncidentEnergy = 0; - break; - } - - } - - // Target - if(m_TargetThickness!=0) - for (G4int i = 0; i < m_TargetNbLayers; i++){ - dedx = emCalculator.ComputeTotalDEDX(IncidentEnergy, Beam, m_TargetMaterial); - de = dedx * ThicknessBeforeInteraction / m_TargetNbLayers; - IncidentEnergy -= de; - if(IncidentEnergy<0){ - IncidentEnergy = 0; - break; - } - - } - } - - if(IncidentEnergy<0) IncidentEnergy = 0 ; - return IncidentEnergy; -} //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... void Target::RandomGaussian2D(double MeanX, double MeanY, double SigmaX, double SigmaY, double &X, double &Y, double NumberOfSigma){ diff --git a/NPSimulation/Core/Target.hh b/NPSimulation/Core/Target.hh index b984a8540e7f59ef101557ceaff59014c80cee10..401057fbe15849429cdf6bb586e734c11381a23b 100644 --- a/NPSimulation/Core/Target.hh +++ b/NPSimulation/Core/Target.hh @@ -75,9 +75,6 @@ public: // (interaction coordinates) are well located inside the target volume bool IsInsideTarget() {return false;}; - // Return the slow down beam energy after interaction at ZInteraction with initial beam energy before target IncidentEnergy - G4double SlowDownBeam(G4ParticleDefinition* Beam, G4double IncidentEnergy, G4double ZInteraction, G4double IncidentTheta); - // Used to simulate beam emmitance effect void RandomGaussian2D(double MeanX, double MeanY, double SigmaX, double SigmaY, double &X, double &Y, double NumberOfSigma = 10000); @@ -94,7 +91,7 @@ public: G4double GetTargetY() {return m_TargetY;} G4double GetTargetZ() {return m_TargetZ;} G4ThreeVector GetTargetPosition() {return G4ThreeVector(m_TargetX,m_TargetY,m_TargetZ);} - G4int GetTargetNbLayers() {return m_TargetNbLayers;} + G4double GetTargetNbSlices() {return m_TargetNbSlices;} G4Tubs* GetTargetSolid() {return m_TargetSolid;} G4LogicalVolume* GetTargetLogic() {return m_TargetLogic;} @@ -113,7 +110,7 @@ private: G4double m_TargetRadius; G4double m_TargetAngle; G4Material* m_TargetMaterial; - G4int m_TargetNbLayers; + G4double m_TargetNbSlices; G4Material* m_TargetBackingMaterial; G4double m_TargetBackingThickness; diff --git a/NPSimulation/Detectors/AGATA/AGATA.cc b/NPSimulation/Detectors/AGATA/AGATA.cc index 8ce56b5fba26ca0cc9a8ab6828e8d2823133ec65..01764809d65953055cfa75607453e3af9392821e 100644 --- a/NPSimulation/Detectors/AGATA/AGATA.cc +++ b/NPSimulation/Detectors/AGATA/AGATA.cc @@ -43,6 +43,7 @@ // NPTool header #include "AGATA.hh" #include "CalorimeterScorers.hh" +#include "InteractionScorers.hh" #include "RootOutput.h" #include "MaterialManager.hh" #include "NPSDetectorFactory.hh" @@ -241,8 +242,10 @@ void AGATA::InitializeScorers() { // Otherwise the scorer is initialised vector<int> level; level.push_back(1); G4VPrimitiveScorer* Calorimeter= new CalorimeterScorers::PS_Calorimeter("Crystal",level, 0) ; + G4VPrimitiveScorer* Interaction= new InteractionScorers::PS_Interactions("Inter",0) ; //and register it to the multifunctionnal detector m_AGATAScorer->RegisterPrimitive(Calorimeter); + m_AGATAScorer->RegisterPrimitive(Interaction); G4SDManager::GetSDMpointer()->AddNewDetector(m_AGATAScorer) ; } diff --git a/NPSimulation/Detectors/Catana/CMakeLists.txt b/NPSimulation/Detectors/Catana/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..1be88727670b88cbb534851f937443710f3d1ee9 --- /dev/null +++ b/NPSimulation/Detectors/Catana/CMakeLists.txt @@ -0,0 +1,2 @@ +add_library(NPSCatana SHARED Catana.cc) +target_link_libraries(NPSCatana NPSCore ${ROOT_LIBRARIES} ${Geant4_LIBRARIES} ${NPLib_LIBRARIES} -lNPCatana) diff --git a/NPSimulation/Detectors/Catana/Catana.cc b/NPSimulation/Detectors/Catana/Catana.cc new file mode 100644 index 0000000000000000000000000000000000000000..bc634efbeb90c3938d68840dd5fd4defa0cf2455 --- /dev/null +++ b/NPSimulation/Detectors/Catana/Catana.cc @@ -0,0 +1,548 @@ +/***************************************************************************** + * Copyright (C) 2009-2020 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 : July 2020 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class describe Catana simulation * + * * + *---------------------------------------------------------------------------* + * Comment: * + * Geometry of crystal based on official catana simulation from Samurai * + * Collaboration package 5.2 * + * http://be.nucl.ap.titech.ac.jp/~nebula/simulator.php * + * Thanks to Togano-san * + * * + *****************************************************************************/ + +// C++ headers +#include <sstream> +#include <fstream> +#include <cmath> +#include <limits> +//G4 Geometry object +#include "G4Tubs.hh" +#include "G4Box.hh" +#include "G4Trap.hh" +#include "G4SubtractionSolid.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 "Catana.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 Catana_NS{ + // Energy and time Resolution + const double EnergyThreshold = 0.1*MeV; + const double ResoTime = 4.5*ns ; + const double ResoEnergy = 0.08*MeV ; + double Length = 600*mm ; + string Material = "CsI"; +} +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +// Catana Specific Method +Catana::Catana(){ + m_Event = new TCatanaData() ; + m_CatanaScorer = 0; + m_DetectorType1 = 0; + m_DetectorType2 = 0; + m_DetectorType3 = 0; + m_DetectorType4 = 0; + m_DetectorType5 = 0; + + // RGB Color + Transparency + m_VisCrystal1 = new G4VisAttributes(G4Colour(0.8, 0.3, 0.3, 1)); + m_VisCrystal2 = new G4VisAttributes(G4Colour(0.3, 0.8, 0.3, 1)); + m_VisCrystal3 = new G4VisAttributes(G4Colour(0.3, 0.3, 0.8, 1)); + m_VisCrystal4 = new G4VisAttributes(G4Colour(0.3, 0.8, 0.8, 1)); + m_VisCrystal5 = new G4VisAttributes(G4Colour(0.8, 0.3, 0.8, 1)); + m_VisHousing = new G4VisAttributes(G4Colour(0.3, 0.3, 0.3, 0.2)); + m_VisReflector = new G4VisAttributes(G4Colour(1, 1, 1, 0.1)); + +} + +Catana::~Catana(){ +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +void Catana::AddDetector(double X,double Y, double Z, double Theta, double Phi, int ID, int Type,double Rshift){ + m_X.push_back(X); + m_Y.push_back(Y); + m_Z.push_back(Z); + m_Theta.push_back(Theta); + m_Phi.push_back(Phi); + m_ID.push_back(ID); + m_Type.push_back(Type); + m_Rshift.push_back(Rshift); +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +void Catana::ReadCSV(string path,double Rshift){ + std::ifstream csv(path); + if(!csv.is_open()){ + std::ostringstream message; + message << "Catana csv file " << path << " not found " << std::endl; + } + + + int ID, type,layer; + double X,Y,Z,Theta,Phi; + string buffer; + // ignore first line + getline(csv,buffer); + while(csv >> ID >> buffer >> type >> buffer >> layer >> buffer >> X >> buffer >> Y >> buffer >> Z >> buffer >> Theta >> buffer >> Phi){ + if(type<6) + AddDetector(X,Y,Z,Theta*deg,Phi*deg,ID,type,Rshift); + else{ + // ignore other type for which I don't have the geometry + } + } + + return; +} +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +G4LogicalVolume* Catana::BuildDetector(int Type){ + // Check if the requested detector already exist + if(Type==1 && m_DetectorType1) + return m_DetectorType1; + + else if(Type==2 && m_DetectorType2) + return m_DetectorType2; + + else if(Type==3 && m_DetectorType3) + return m_DetectorType3; + + else if(Type==4 && m_DetectorType4) + return m_DetectorType4; + + else if(Type==5 && m_DetectorType5) + return m_DetectorType5; + + + // Define the requested geometry + double x1,x2,x3,x4,y1,y2,z,crystalz; + //int pmttype; // 1: H7195, 2:H11934 + double seal_dt = 12*mm, housing_dt = 0.5*mm, reflector_dt = 0.5*mm; + + if(Type == 1){ // crystal type 1 + x1 = 62.3*mm; x2 = 62.3*mm; x3 = 95.7*mm; y1 = 36.6*mm; y2 = 56.3*mm; + z = 107*mm; crystalz = 93.*mm; //pmttype = 1; + } + if(Type == 2){ // crystal type 2 + x1 = 57.1*mm; x2 = 63.6*mm; x3 = 84.5*mm; y1 = 34.9*mm; y2 = 55.4*mm; + z = 117*mm; crystalz = 103.*mm; //pmttype = 1; + } + if(Type == 3){ // crystal type 3 + x1 = 49.7*mm; x2 = 58.5*mm; x3 = 74.9*mm; y1 = 38.3*mm; y2 = 64.7*mm; + z = 137*mm; crystalz = 123.*mm; //pmttype = 1; + } + if(Type == 4){ // crystal type 4 + x1 = 40.0*mm; x2 = 50.2*mm; x3 = 60.3*mm; y1 = 38.3*mm; y2 = 66.4*mm; + z = 152*mm; crystalz = 138.5*mm; //pmttype = 1; + } + if(Type == 5){ // crystal type 5 + x1 = 28.4*mm; x2 = 39.7*mm; x3 = 41.5*mm; y1 = 38.3*mm; y2 = 69.9*mm; + z = 162*mm; crystalz = 148.5*mm; //pmttype = 2; + } + x4 = x3 + (y2/y1)*(x2-x1); // planarity condition + Double_t beta1 = 90*deg + std::atan((x2-x1)/(y1*2));// should be + Double_t beta2 = 90*deg + std::atan((x4-x3)/(y2*2));// beta1 = beta2 + if(std::abs(beta1-beta2)>1e-4){ + std::cout << "Housing type " << Type << " is not planar" << std::endl; + } + + // Define Material + G4Material* CsI = MaterialManager::getInstance()->GetMaterialFromLibrary("CsI"); + G4Material* Al = MaterialManager::getInstance()->GetMaterialFromLibrary("Al"); + G4Material* Vacuum= MaterialManager::getInstance()->GetMaterialFromLibrary("Vacuum"); + G4Material* Teflon= MaterialManager::getInstance()->GetMaterialFromLibrary("G4_TEFLON"); + G4RotationMatrix* Rot= new G4RotationMatrix(); + + + // Parameters for G4Trap + double pDz, pDy1, pDy2, pDx1, pDx2, pDx3, pDx4; + double pTheta=0.*deg, pPhi=0.*deg, pAlp1=0.*deg, pAlp2=0*deg; + + // housing outside + pDz = z*0.5; + pDy1 = y1*0.5; + pDy2 = y2*0.5; + pDx1 = x1*0.5; + pDx2 = x2*0.5; + pDx3 = x3*0.5; + pDx4 = x4*0.5; + + G4Trap *solidHousingOUT = new G4Trap("solidHousingOut", pDz, pTheta, pPhi, + pDy1, pDx1, pDx2, pAlp1, pDy2, pDx3, + pDx4, pAlp2); + + G4LogicalVolume* result = 0; + if(Type==1){ + m_DetectorType1 = new G4LogicalVolume(solidHousingOUT, + Vacuum, + "logicDetectorType1", + 0,0,0); + result = m_DetectorType1; + } + else if(Type==2){ + m_DetectorType2 = new G4LogicalVolume(solidHousingOUT, + Vacuum, + "logicDetectorType2", + 0,0,0); + result = m_DetectorType2; + } + + + else if(Type==3){ + m_DetectorType3 = new G4LogicalVolume(solidHousingOUT, + Vacuum, + "logicDetectorType3", + 0,0,0); + result = m_DetectorType3; + } + + + else if(Type==4){ + m_DetectorType4 = new G4LogicalVolume(solidHousingOUT, + Vacuum, + "logicDetectorType4", + 0,0,0); + result = m_DetectorType4; + } + + else if(Type==5){ + m_DetectorType5 = new G4LogicalVolume(solidHousingOUT, + Vacuum, + "logicDetectorType5", + 0,0,0); + result = m_DetectorType5; + } + + + result->SetVisAttributes(G4VisAttributes::Invisible); + + + // -- Al housing inside + double length = z; + double ax1 = pDx1; + double bx1 = pDx3; + double ax2 = pDx2; + double bx2 = pDx4; + double ay1 = pDy1; + double by1 = pDy2; + + pDz = (length - seal_dt - housing_dt)/2.; + pDy1 = (by1-ay1)/length * housing_dt + ay1 - housing_dt; + pDx1 = (bx1-ax1)/length * housing_dt + ax1 - housing_dt; + pDx2 = (bx2-ax2)/length * housing_dt + ax2 - housing_dt; + pDy2 = (by1-ay1)/length * (length - seal_dt) + ay1 - housing_dt; + pDx3 = (bx1-ax1)/length * (length - seal_dt) + ax1 - housing_dt; + //pDx4 = (bx2-ax2)/length * (length - seal_dt) + ax2 - housing_dt; + pDx4 = pDx3 + (pDy2 / pDy1)*(pDx2 - pDx1); // planarity condition + + G4Trap* solidHousingIN = new G4Trap("solidHousingIN", pDz, pTheta, pPhi, + pDy1, pDx1, pDx2, pAlp1, pDy2, pDx3, + pDx4, pAlp2); + + + double offset = -(length*0.5 - pDz - housing_dt); + G4SubtractionSolid* solidHousing = + new G4SubtractionSolid("solidHousing", solidHousingOUT,// mother + solidHousingIN, Rot, + G4ThreeVector(0.,0.,offset)); + + G4LogicalVolume* LogicHousing = new G4LogicalVolume(solidHousing, Al,"logicHousing",0,0,0); + LogicHousing->SetVisAttributes(m_VisHousing); + + // -- Crystal -- + double space = 2.*mm; // space btw. crystal and housing + length = pDz * 2.; // housing inner z length + ax1 = pDx1; + bx1 = pDx3; + ax2 = pDx2; + bx2 = pDx4; + ay1 = pDy1; + by1 = pDy2; + + pDz = crystalz*0.5; + pDy1 = (by1-ay1)/length * reflector_dt + ay1 - space; + pDx1 = (bx1-ax1)/length * reflector_dt + ax1 - space; + pDx2 = (bx2-ax2)/length * reflector_dt + ax2 - space; + pDy2 = (by1-ay1)/length * (reflector_dt + crystalz) + ay1 - space; + pDx3 = (bx1-ax1)/length * (reflector_dt + crystalz) + ax1 - space; + //pDx4 = (bx2-ax2)/length * (reflector_dt + crystalz) + ax2 - space; + pDx4 = pDx3 + (pDy2 / pDy1)*(pDx2 - pDx1); // planarity condition + + G4Trap* solidCrystal = new G4Trap("solidCrystal", pDz, pTheta, pPhi, + pDy1, pDx1, pDx2, pAlp1, pDy2, pDx3, + pDx4, pAlp2); + + G4LogicalVolume* LogicCrystal = new G4LogicalVolume(solidCrystal,// solid + CsI, + "SolidCrystal", + 0,0,0); + if(Type==1) + LogicCrystal->SetVisAttributes(m_VisCrystal1); + + else if(Type==2) + LogicCrystal->SetVisAttributes(m_VisCrystal2); + + else if(Type==3) + LogicCrystal->SetVisAttributes(m_VisCrystal3); + + else if(Type==4) + LogicCrystal->SetVisAttributes(m_VisCrystal4); + + else if(Type==5) + LogicCrystal->SetVisAttributes(m_VisCrystal5); + + + LogicCrystal->SetSensitiveDetector(m_CatanaScorer); + + // -- Teflon reflector + length = crystalz; + ax1 = pDx1; + bx1 = pDx3; + ax2 = pDx2; + bx2 = pDx4; + ay1 = pDy1; + by1 = pDy2; + + pDz = crystalz*0.5 + reflector_dt; + pDy1 = (by1-ay1)/length * -reflector_dt + ay1 + reflector_dt; + pDx1 = (bx1-ax1)/length * -reflector_dt + ax1 + reflector_dt; + pDx2 = (bx2-ax2)/length * -reflector_dt + ax2 + reflector_dt; + pDy2 = (by1-ay1)/length * (reflector_dt + crystalz) + ay1 + reflector_dt; + pDx3 = (bx1-ax1)/length * (reflector_dt + crystalz) + ax1 + reflector_dt; + //pDx4 = (bx2-ax2)/length * (reflector_dt + crystalz) + ax2 + reflector_dt; + pDx4 = pDx3 + (pDy2 / pDy1)*(pDx2 - pDx1); // planarity condition + + G4Trap* solidReflector = new G4Trap("solidReflector",pDz, pTheta, + pPhi, pDy1, pDx1, pDx2, pAlp1, + pDy2, pDx3, pDx4, pAlp2); + + G4LogicalVolume* LogicReflector = new G4LogicalVolume(solidReflector, Teflon, + "logicReflector", + 0,0,0); + + LogicReflector->SetVisAttributes(m_VisReflector); + + // Place volume in each other: + new G4PVPlacement(G4Transform3D(*Rot,G4ThreeVector(0,0,0)), + LogicHousing, + "CatanaHousing",result,false,0); + + + m_Zoffset[Type] = (z - crystalz)*0.5 - housing_dt - reflector_dt; + + new G4PVPlacement(G4Transform3D(*Rot,G4ThreeVector(0,0,-m_Zoffset[Type])), + LogicReflector, + "CatanaReflector",result,false,0); + + new G4PVPlacement(G4Transform3D(*Rot,G4ThreeVector(0,0,0)), + LogicCrystal, + "CatanaCrystal",LogicReflector,false,0); + + return result; + +} + +//....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 Catana::ReadConfiguration(NPL::InputParser parser){ + // CSV config + vector<NPL::InputBlock*> blocks = parser.GetAllBlocksWithTokenAndValue("Catana","CSV"); + if(NPOptionManager::getInstance()->GetVerboseLevel()) + cout << "//// " << blocks.size() << " CSV block found " << endl; + + vector<string> token = {"Path","Pos","Rshift"}; + + for(unsigned int i = 0 ; i < blocks.size() ; i++){ + if(blocks[i]->HasTokenList(token)){ + if(NPOptionManager::getInstance()->GetVerboseLevel()) + cout << endl << "//// Catana " << i+1 << endl; + string path = blocks[i]->GetString("Path"); + double Rshift = blocks[i]->GetDouble("Rshift","micrometer"); + // Reference position of the whole array + m_Ref = NPS::ConvertVector(blocks[i]->GetTVector3("Pos","mm")); + ReadCSV(path,Rshift); + } + else{ + cout << "ERROR: check your input file formatting " << endl; + exit(1); + } + } + + // Type 1 + blocks = parser.GetAllBlocksWithTokenAndValue("Catana","Detector"); + if(NPOptionManager::getInstance()->GetVerboseLevel()) + cout << "//// " << blocks.size() << " detectors found " << endl; + + token = {"X","Y","Z","Theta","Phi","ID","Type"}; + + for(unsigned int i = 0 ; i < blocks.size() ; i++){ + if(blocks[i]->HasTokenList(token)){ + if(NPOptionManager::getInstance()->GetVerboseLevel()) + cout << endl << "//// Catana " << i+1 << endl; + double X = blocks[i]->GetDouble("X","mm"); + double Y = blocks[i]->GetDouble("Y","mm"); + double Z = blocks[i]->GetDouble("Z","mm"); + double Theta = blocks[i]->GetDouble("Theta","deg"); + double Phi = blocks[i]->GetDouble("Phi","deg"); + int ID = blocks[i]->GetInt("ID"); + int Type = blocks[i]->GetInt("Type"); + AddDetector(X,Y,Z,Theta,Phi,ID,Type); + } + 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 Catana::ConstructDetector(G4LogicalVolume* world){ + for (unsigned short i = 0 ; i < m_X.size() ; i++) { + if(m_Type[i]>5) + exit(1); + BuildDetector(m_Type[i]); + // Reference coordinate given for center of crystal + G4ThreeVector Det_pos = G4ThreeVector(m_X[i],m_Y[i],m_Z[i]) ; + // But placed volume is casing which is shifted w/respect to crystal + G4ThreeVector Det_dir = Det_pos; + Det_dir.unit(); + // had to add a 70micron in radius to avoid overlap when using official + // csv simulation file + Det_dir.setMag(m_Zoffset[m_Type[i]]+m_Rshift[i]); + Det_pos+=Det_dir+m_Ref; + G4RotationMatrix* Rot = new G4RotationMatrix(); + Rot->rotateX(-m_Theta[i]); + Rot->rotateZ(m_Phi[i]); + new G4PVPlacement(G4Transform3D(*Rot,Det_pos), + BuildDetector(m_Type[i]), + "Catana",world,false,m_ID[i]); + } +} +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +// Add Detector branch to the EventTree. +// Called After DetecorConstruction::AddDetector Method +void Catana::InitializeRootOutput(){ + RootOutput *pAnalysis = RootOutput::getInstance(); + TTree *pTree = pAnalysis->GetTree(); + if(!pTree->FindBranch("Catana")){ + pTree->Branch("Catana", "TCatanaData", &m_Event) ; + } + pTree->SetBranchAddress("Catana", &m_Event) ; +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +// Read sensitive part and fill the Root tree. +// Called at in the EventAction::EndOfEventAvtion +void Catana::ReadSensitive(const G4Event* ){ + m_Event->Clear(); + + /////////// + // Calorimeter scorer + CalorimeterScorers::PS_Calorimeter* Scorer= (CalorimeterScorers::PS_Calorimeter*) m_CatanaScorer->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),Catana_NS::ResoEnergy); + if(Energy>Catana_NS::EnergyThreshold){ + double Time = RandGauss::shoot(Scorer->GetTime(i),Catana_NS::ResoTime); + int DetectorNbr = level[0]; + m_Event->SetEnergy(DetectorNbr,Energy); + m_Event->SetTime(DetectorNbr,Time); + } + } +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//////////////////////////////////////////////////////////////// +void Catana::InitializeScorers() { + // This check is necessary in case the geometry is reloaded + bool already_exist = false; + m_CatanaScorer = CheckScorer("CatanaScorer",already_exist) ; + + if(already_exist) + return ; + + // Otherwise the scorer is initialised + vector<int> level; level.push_back(2); + 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_CatanaScorer->RegisterPrimitive(Calorimeter); + m_CatanaScorer->RegisterPrimitive(Interaction); + G4SDManager::GetSDMpointer()->AddNewDetector(m_CatanaScorer) ; +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//////////////////////////////////////////////////////////////////////////////// +// Construct Method to be pass to the DetectorFactory // +//////////////////////////////////////////////////////////////////////////////// +NPS::VDetector* Catana::Construct(){ + return (NPS::VDetector*) new Catana(); +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//////////////////////////////////////////////////////////////////////////////// +// Registering the construct method to the factory // +//////////////////////////////////////////////////////////////////////////////// +extern"C" { + class proxy_nps_Catana{ + public: + proxy_nps_Catana(){ + NPS::DetectorFactory::getInstance()->AddToken("Catana","Catana"); + NPS::DetectorFactory::getInstance()->AddDetector("Catana",Catana::Construct); + } + }; + + proxy_nps_Catana p_nps_Catana; +} diff --git a/NPSimulation/Detectors/Catana/Catana.hh b/NPSimulation/Detectors/Catana/Catana.hh new file mode 100644 index 0000000000000000000000000000000000000000..2157ceb0c83842891acf79f7d6b7eea0a766f52d --- /dev/null +++ b/NPSimulation/Detectors/Catana/Catana.hh @@ -0,0 +1,139 @@ +#ifndef Catana_h +#define Catana_h 1 +/***************************************************************************** + * Copyright (C) 2009-2020 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 : July 2020 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class describe Catana simulation * + * * + *---------------------------------------------------------------------------* + * Comment: * + * Geometry of crystal based on official catana simulation from Samurai * + * Collaboration package 5.2 * + * http://be.nucl.ap.titech.ac.jp/~nebula/simulator.php * + * Thanks to Togano-san * + * * + *****************************************************************************/ + +// 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 "TCatanaData.h" +#include "NPInputParser.h" + +class Catana : public NPS::VDetector{ + //////////////////////////////////////////////////// + /////// Default Constructor and Destructor ///////// + //////////////////////////////////////////////////// + public: + Catana() ; + virtual ~Catana() ; + + //////////////////////////////////////////////////// + /////// Specific Function of this Class /////////// + //////////////////////////////////////////////////// + public: + // Cartesian + void AddDetector(double X, double Y, double Z, double Theta, double Phi, int ID,int Type,double Rshift=0); + void ReadCSV(string path,double Rshift); + + G4LogicalVolume* BuildDetector(int Type); + + private: + G4LogicalVolume* m_DetectorType1; + G4LogicalVolume* m_DetectorType2; + G4LogicalVolume* m_DetectorType3; + G4LogicalVolume* m_DetectorType4; + G4LogicalVolume* m_DetectorType5; + + + //////////////////////////////////////////////////// + ////// 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_CatanaScorer ; + //////////////////////////////////////////////////// + ///////////Event class to store Data//////////////// + //////////////////////////////////////////////////// + private: + TCatanaData* m_Event ; + + //////////////////////////////////////////////////// + ///////////////Private intern Data////////////////// + //////////////////////////////////////////////////// + private: // Geometry + // Detector Coordinate + vector<double> m_X; + vector<double> m_Y; + vector<double> m_Z; + vector<double> m_Theta; + vector<double> m_Phi; + vector<int> m_ID; + vector<int> m_Type; + G4ThreeVector m_Ref; + // this parameter is here because some csv file have very small overlap + // due to difference between mechanical design and reality of the detector + // a shift is apply to the position of the crystal to slightly icrease the radius + // and avoid shift. Typical value shoulde be < 100um + vector<double> m_Rshift;// additional shift to apply to csv file + // relative shift of crystal w/r to the housing + map<int,double> m_Zoffset; + + // Visualisation Attribute + G4VisAttributes* m_VisCrystal1; + G4VisAttributes* m_VisCrystal2; + G4VisAttributes* m_VisCrystal3; + G4VisAttributes* m_VisCrystal4; + G4VisAttributes* m_VisCrystal5; + + G4VisAttributes* m_VisHousing; + G4VisAttributes* m_VisReflector; + + + + // Needed for dynamic loading of the library + public: + static NPS::VDetector* Construct(); +}; +#endif diff --git a/NPSimulation/Detectors/LightPipe/LightPipe.cc b/NPSimulation/Detectors/LightPipe/LightPipe.cc index c9465f09ded7f55d798f72e90712e83ccef29ab3..b9c0ee23aa1088b4f0d472182edd49e4df920e1b 100644 --- a/NPSimulation/Detectors/LightPipe/LightPipe.cc +++ b/NPSimulation/Detectors/LightPipe/LightPipe.cc @@ -1,18 +1,18 @@ /***************************************************************************** - * Copyright (C) 2009-2018 this file is part of the NPTool Project * + * Copyright (C) 2009-2018 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: Greg Christian contact address: gchristian@tamu.edu * + * Original Author: Greg Christian contact address: gchristian@tamu.edu * * * - * Creation Date : July 2018 * + * Creation Date : July 2018 * * Last update : * *---------------------------------------------------------------------------* * Decription: * - * This class describe LightPipe simulation * + * This class describe LightPipe simulation * * * *---------------------------------------------------------------------------* * Comment: * @@ -75,7 +75,8 @@ LightPipe::LightPipe(){ m_VisPD = new G4VisAttributes(G4Colour(0.1, 0.2, 0.3)); m_ScintillatorMaterial = CreateScintillatorMaterial(); m_PipeMaterial = CreatePipeMaterial(); - //m_Wrapping = CreateWrappingMaterial(); + //m_WrappingMaterial = CreateWrappingMaterial(); +// m_WrappingMaterial = NULL; m_ReflectiveSurface = CreateReflectiveSurface(); m_VisSquare->SetForceWireframe(true); diff --git a/NPSimulation/Detectors/Miniball/Miniball.cc b/NPSimulation/Detectors/Miniball/Miniball.cc index 04821fddda63dcb6daa37af7c9dbd2cdb53041f5..0da1686617c935f21e1078cbc970f3337309f91d 100644 --- a/NPSimulation/Detectors/Miniball/Miniball.cc +++ b/NPSimulation/Detectors/Miniball/Miniball.cc @@ -58,7 +58,7 @@ namespace Miniball_NS{ const double EnergyThreshold = 0.01*MeV; const double ResoTime = 4.5*ns ; const double ResoEnergy = 0.003*MeV ; - //const double ResoAngle = 5*deg; + const double ResoAngle = 5*deg; } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... diff --git a/NPSimulation/Detectors/Mugast/Mugast.cc b/NPSimulation/Detectors/Mugast/Mugast.cc index ac90486a5a5c7528eae92fa59c26b0db4a4f5945..6efd81e8ba5b9b6a76eb3041e2a35b917f036412 100644 --- a/NPSimulation/Detectors/Mugast/Mugast.cc +++ b/NPSimulation/Detectors/Mugast/Mugast.cc @@ -64,7 +64,7 @@ using namespace CLHEP; namespace Mugast_NS{ // Resolution const G4double SigmaTime = 0.212765957 ;// = 500ps - const G4double SigmaEnergy = 0.0149 ;// 0.0223 = 52keV of Resolution // Unit is MeV/2.35 14.861996 + const G4double SigmaEnergy = 0.019 ;// // const G4double TimeOffset = 500 ;// 500 ns stop // Threshold @@ -72,7 +72,7 @@ namespace Mugast_NS{ // Geometry //const G4double AluStripThickness = 0.4*micrometer ; - const G4double SiliconThickness = 3000*micrometer ; + const G4double SiliconThickness = 300*micrometer ; // Square @@ -230,6 +230,7 @@ G4LogicalVolume* Mugast::BuildTrapezoidDetector(){ //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... G4LogicalVolume* Mugast::BuildAnnularDetector(){ + if(!m_AnnularDetector){ G4Material* Silicon = MaterialManager::getInstance()->GetMaterialFromLibrary("Si"); G4Material* Vacuum = MaterialManager::getInstance()->GetMaterialFromLibrary("Vacuum"); @@ -382,7 +383,6 @@ G4LogicalVolume* Mugast::BuildAnnularDetector(){ // Set Silicon strip sensible logicActiveWafer->SetSensitiveDetector(m_AnnularScorer); } - return m_AnnularDetector; } diff --git a/NPSimulation/Detectors/Strasse/CMakeLists.txt b/NPSimulation/Detectors/Strasse/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..5995a705be35995b6e0306ac445fedd0f4d334e6 --- /dev/null +++ b/NPSimulation/Detectors/Strasse/CMakeLists.txt @@ -0,0 +1,2 @@ +add_library(NPSStrasse SHARED Strasse.cc) +target_link_libraries(NPSStrasse NPSCore ${ROOT_LIBRARIES} ${Geant4_LIBRARIES} ${NPLib_LIBRARIES} -lNPStrasse) diff --git a/NPSimulation/Detectors/Strasse/Strasse.cc b/NPSimulation/Detectors/Strasse/Strasse.cc new file mode 100644 index 0000000000000000000000000000000000000000..ac019f11aef536ef8264272554e328551105854d --- /dev/null +++ b/NPSimulation/Detectors/Strasse/Strasse.cc @@ -0,0 +1,978 @@ +/***************************************************************************** + * Copyright (C) 2009-2020 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: A. Matta contact address: matta@lpccaen.in2p3.fr * + * * + * Creation Date : July 2020 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class describe Strasse simulation * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + *****************************************************************************/ + +// C++ headers +#include <sstream> +#include <cmath> +#include <limits> +//G4 Geometry object +#include "G4Tubs.hh" +#include "G4Box.hh" +#include "G4Sphere.hh" +#include "G4UnionSolid.hh" +#include "G4ExtrudedSolid.hh" +#include "G4SubtractionSolid.hh" +#include "G4TwoVector.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 "Strasse.hh" +#include "DSSDScorers.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 Strasse_NS{ + // Energy and time Resolution + const double EnergyThreshold = 10*keV; + const double ResoEnergy = 0.015*MeV ; + + //////////////////// + // Inner Detector // + //////////////////// + // Wafer parameter + double Inner_Wafer_Length=100*mm; + double Inner_Wafer_Width=50*mm; + double Inner_Wafer_Thickness=300*micrometer; + double Inner_Wafer_AlThickness=0.4*micrometer; + double Inner_Wafer_PADExternal=1*cm; + double Inner_Wafer_PADInternal=1*mm; + double Inner_Wafer_GuardRing=0.5*mm; + + // PCB parameter + double Inner_PCB_PortWidth=1*cm; + double Inner_PCB_StarboardWidth=2*mm; + double Inner_PCB_BevelAngle= 60*deg; + double Inner_PCB_UpstreamWidth=1*cm; + double Inner_PCB_DownstreamWidth=2*mm; + double Inner_PCB_MidWidth=2*mm; + double Inner_PCB_Thickness=3*mm; + double Inner_Wafer_TransverseStrips= 128; + double Inner_Wafer_LongitudinalStrips= 128; + + //////////////////// + // Outer Detector // + //////////////////// + // Wafer parameter + double Outer_Wafer_Length=150*mm; + double Outer_Wafer_Width=75*mm; + double Outer_Wafer_Thickness=300*micrometer; + double Outer_Wafer_AlThickness=0.4*micrometer; + double Outer_Wafer_PADExternal=1*cm; + double Outer_Wafer_PADInternal=1*mm; + double Outer_Wafer_GuardRing=0.5*mm; + + // PCB parameter + double Outer_PCB_PortWidth=1*cm; + double Outer_PCB_StarboardWidth=2*mm; + double Outer_PCB_BevelAngle= 60*deg; + double Outer_PCB_UpstreamWidth=1*cm; + double Outer_PCB_DownstreamWidth=2*mm; + double Outer_PCB_MidWidth=2*mm; + double Outer_PCB_Thickness=3*mm; + double Outer_Wafer_TransverseStrips= 128; + double Outer_Wafer_LongitudinalStrips= 128; + + //////////////////// + // Vacuum Chamber // + //////////////////// + double Chamber_Thickness= 3*mm; + double Chamber_Cylinder_Length= 400*mm; + double Chamber_Radius= 180*mm; + double Chamber_ExitTube_Radius= 79.5*mm ; + double Chamber_ExitTube_Length= 100*mm; + double Chamber_Flange_Inner_Radius= 150*mm; + double Chamber_Sphere_Radius= 220*mm ; + double Chamber_Sphere_Shift= 60*mm; + +} + +using namespace Strasse_NS; +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +// Strasse Specific Method +Strasse::Strasse(){ + InitializeMaterial(); + m_Event = new TStrasseData() ; + m_InnerScorer1 = 0; + m_OuterScorer1 = 0; + m_InnerScorer2 = 0; + m_OuterScorer2 = 0; + m_InnerDetector=0; + m_OuterDetector=0; + m_Chamber=0; + m_Frame=0; + m_Electronic=0; + // Dark Grey + SiliconVisAtt = new G4VisAttributes(G4Colour(0.5, 0.5, 0.5)) ; + // Green + PCBVisAtt = new G4VisAttributes(G4Colour(0.2, 0.5, 0.2)) ; + // Gold Yellow + PADVisAtt = new G4VisAttributes(G4Colour(0.5, 0.5, 0.2)) ; + // Light Grey + FrameVisAtt = new G4VisAttributes(G4Colour(0.5, 0.5, 0.5)) ; + // Space transparent + ChamberVisAtt = new G4VisAttributes(G4Colour(0.3, 0.4, 0.5,0.2)) ; + // Light Blue + GuardRingVisAtt = new G4VisAttributes(G4Colour(0, 0, 0,0.5)) ; +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +Strasse::~Strasse(){ +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +void Strasse::AddInnerDetector(double R, double Z, double Phi, double Shift, G4ThreeVector Ref){ + m_Inner_R.push_back(R); + m_Inner_Z.push_back(Z); + m_Inner_Phi.push_back(Phi); + m_Inner_Shift.push_back(Shift); + m_Inner_Ref.push_back(Ref); +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +void Strasse::AddOuterDetector(double R, double Z, double Phi, double Shift, G4ThreeVector Ref){ + m_Outer_R.push_back(R); + m_Outer_Z.push_back(Z); + m_Outer_Phi.push_back(Phi); + m_Outer_Shift.push_back(Shift); + m_Outer_Ref.push_back(Ref); +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +void Strasse::AddChamber(double Z){ + m_Chamber_Z.push_back(Z); +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +G4LogicalVolume* Strasse::BuildInnerDetector(){ + if(!m_InnerDetector){ + // Compute the needed full length of the PCB + // along beam axis + double Inner_PCB_Length= 2*Inner_Wafer_Length + +Inner_PCB_UpstreamWidth + +Inner_PCB_MidWidth + +Inner_PCB_DownstreamWidth; + + // perpendicular to beam axis + double Inner_PCB_Width= Inner_Wafer_Width + +Inner_PCB_StarboardWidth + +Inner_PCB_PortWidth; + + + vector<G4TwoVector> PCBCrossSection; + double l1 = Inner_PCB_Thickness*0.5/tan(Inner_PCB_BevelAngle); + + PCBCrossSection.push_back(G4TwoVector(Inner_PCB_Width*0.5-l1,-Inner_PCB_Thickness*0.5)); + PCBCrossSection.push_back(G4TwoVector(Inner_PCB_Width*0.5,Inner_PCB_Thickness*0.5)); + PCBCrossSection.push_back(G4TwoVector(-Inner_PCB_Width*0.5-l1,Inner_PCB_Thickness*0.5)); + PCBCrossSection.push_back(G4TwoVector(-Inner_PCB_Width*0.5,-Inner_PCB_Thickness*0.5)); + + G4ExtrudedSolid* PCBFull = + new G4ExtrudedSolid("PCBFull", + PCBCrossSection, + Inner_PCB_Length*0.5,// half length + G4TwoVector(0,0),1,// offset, scale + G4TwoVector(0,0),1);// offset, scale + + // Master Volume that encompass everything else + m_InnerDetector = + new G4LogicalVolume(PCBFull,m_MaterialVacuum,"logicBoxDetector", 0, 0, 0); + m_InnerDetector->SetVisAttributes(G4VisAttributes::Invisible); + + // Build the PCB + // Calculate the hole shift within the PCB + double Width_Shift= -0.5*Inner_PCB_Width + 0.5*Inner_Wafer_Width // Flush to border + +Inner_PCB_PortWidth; // add the port side shift + + double Length_Shift1 = -0.5*Inner_PCB_Length + 0.5*Inner_Wafer_Length // Flush to border + + Inner_PCB_UpstreamWidth;// add Upstream side shift + + double Length_Shift2 = Length_Shift1 // overlap detector 1 + + Inner_Wafer_Length // at opposing edge + + Inner_PCB_MidWidth; // after mid width + + G4ThreeVector HoleShift1 = G4ThreeVector(Width_Shift, 0, Length_Shift1); + G4ThreeVector HoleShift2 = G4ThreeVector(Width_Shift, 0, Length_Shift2); + + G4Box* HoleShape = new G4Box("HoleShape", + Inner_Wafer_Width*0.5, + Inner_PCB_Thickness*0.5+0.1*mm, + Inner_Wafer_Length*0.5); + + // Substracting the hole Shape from the Stock PCB + G4SubtractionSolid* PCB_1 = new G4SubtractionSolid("PCB_1", PCBFull, HoleShape, + new G4RotationMatrix,HoleShift1); + G4SubtractionSolid* PCB = new G4SubtractionSolid("PCB", PCB_1, HoleShape, + new G4RotationMatrix,HoleShift2); + + // Sub Volume PCB + G4LogicalVolume* logicPCB = + new G4LogicalVolume(PCB,m_MaterialPCB,"logicPCB", 0, 0, 0); + logicPCB->SetVisAttributes(PCBVisAtt); + + new G4PVPlacement(new G4RotationMatrix(0,0,0), + G4ThreeVector(0,0,0), + logicPCB,"Strasse_Inner_PCB",m_InnerDetector, + false,0); + + // Sub volume Wafer + G4Box* WaferShape = new G4Box("WaferShape", + Inner_Wafer_Width*0.5, + Inner_Wafer_Thickness*0.5+Inner_Wafer_AlThickness, + Inner_Wafer_Length*0.5); + + G4LogicalVolume* logicWafer1 = + new G4LogicalVolume(WaferShape,m_MaterialSilicon,"logicWafer1", 0, 0, 0); + logicWafer1->SetVisAttributes(GuardRingVisAtt); + + G4LogicalVolume* logicWafer2 = + new G4LogicalVolume(WaferShape,m_MaterialSilicon,"logicWafer2", 0, 0, 0); + logicWafer2->SetVisAttributes(GuardRingVisAtt); + + + new G4PVPlacement(new G4RotationMatrix(0,0,0), + G4ThreeVector(0,0.5*Inner_Wafer_Thickness + +Inner_Wafer_AlThickness + -0.5*Inner_PCB_Thickness,0)// flush the wafer to the pcb on one side + +HoleShift1, // Shift wafer in the hole + logicWafer1,"Strasse_Inner_Wafer1",m_InnerDetector, + false,0); + + new G4PVPlacement(new G4RotationMatrix(0,0,0), + G4ThreeVector(0,0.5*Inner_Wafer_Thickness + +Inner_Wafer_AlThickness + -0.5*Inner_PCB_Thickness,0)// flush the wafer to the pcb on one side + +HoleShift2, // Shift wafer in the hole + logicWafer2,"Strasse_Inner_Wafer2",m_InnerDetector, + false,0); + + // Sub volume Active Wafer + G4Box* ActiveWaferShape = new G4Box("InnerActiveWaferShape", + 0.5*m_Active_InnerWafer_Width, + 0.5*Inner_Wafer_Thickness, + 0.5*m_Active_InnerWafer_Length); + + G4LogicalVolume* logicActiveWafer1 = + new G4LogicalVolume(ActiveWaferShape,m_MaterialSilicon,"logicActiveWafer1", 0, 0, 0); + logicActiveWafer1->SetVisAttributes(SiliconVisAtt); + logicActiveWafer1->SetSensitiveDetector(m_InnerScorer1); + + G4LogicalVolume* logicActiveWafer2 = + new G4LogicalVolume(ActiveWaferShape,m_MaterialSilicon,"logicActiveWafer2", 0, 0, 0); + logicActiveWafer2->SetVisAttributes(SiliconVisAtt); + logicActiveWafer2->SetSensitiveDetector(m_InnerScorer2); + + + + new G4PVPlacement(new G4RotationMatrix(0,0,0), + G4ThreeVector(0,0,0.5*(Inner_Wafer_PADExternal-Inner_Wafer_PADInternal)), // assymetric pading for bounding + logicActiveWafer1,"Strasse_Inner_ActiveWafer1",logicWafer1, + false,1); + + new G4PVPlacement(new G4RotationMatrix(0,0,0), + G4ThreeVector(0,0,-0.5*(Inner_Wafer_PADExternal-Inner_Wafer_PADInternal)), // assymetric pading for bounding + logicActiveWafer2,"Strasse_Inner_ActiveWafer2",logicWafer2, + false,2); + } + return m_InnerDetector; +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +G4LogicalVolume* Strasse::BuildOuterDetector(){ + if(!m_OuterDetector){ + // Compute the needed full length of the PCB + // along beam axis + double Outer_PCB_Length= 2*Outer_Wafer_Length + +Outer_PCB_UpstreamWidth + +Outer_PCB_MidWidth + +Outer_PCB_DownstreamWidth; + + // perpendicular to beam axis + double Outer_PCB_Width= Outer_Wafer_Width + +Outer_PCB_StarboardWidth + +Outer_PCB_PortWidth; + + + vector<G4TwoVector> PCBCrossSection; + double l1 = Outer_PCB_Thickness*0.5/tan(Outer_PCB_BevelAngle); + + PCBCrossSection.push_back(G4TwoVector(Outer_PCB_Width*0.5-l1,-Outer_PCB_Thickness*0.5)); + PCBCrossSection.push_back(G4TwoVector(Outer_PCB_Width*0.5,Outer_PCB_Thickness*0.5)); + PCBCrossSection.push_back(G4TwoVector(-Outer_PCB_Width*0.5-l1,Outer_PCB_Thickness*0.5)); + PCBCrossSection.push_back(G4TwoVector(-Outer_PCB_Width*0.5,-Outer_PCB_Thickness*0.5)); + + G4ExtrudedSolid* PCBFull = + new G4ExtrudedSolid("PCBFull", + PCBCrossSection, + Outer_PCB_Length*0.5,// half length + G4TwoVector(0,0),1,// offset, scale + G4TwoVector(0,0),1);// offset, scale + + // Master Volume that encompass everything else + m_OuterDetector = + new G4LogicalVolume(PCBFull,m_MaterialVacuum,"logicBoxDetector", 0, 0, 0); + m_OuterDetector->SetVisAttributes(G4VisAttributes::Invisible); + + // Build the PCB + // Calculate the hole shift within the PCB + double Width_Shift= -0.5*Outer_PCB_Width + 0.5*Outer_Wafer_Width // Flush to border + +Outer_PCB_PortWidth; // add the port side shift + + double Length_Shift1 = -0.5*Outer_PCB_Length + 0.5*Outer_Wafer_Length // Flush to border + + Outer_PCB_UpstreamWidth;// add Upstream side shift + + double Length_Shift2 = Length_Shift1 // overlap detector 1 + + Outer_Wafer_Length // at opposing edge + + Outer_PCB_MidWidth; // after mid width + + G4ThreeVector HoleShift1 = G4ThreeVector(Width_Shift, 0, Length_Shift1); + G4ThreeVector HoleShift2 = G4ThreeVector(Width_Shift, 0, Length_Shift2); + + G4Box* HoleShape = new G4Box("HoleShape", + Outer_Wafer_Width*0.5, + Outer_PCB_Thickness*0.5+0.1*mm, + Outer_Wafer_Length*0.5); + + // Substracting the hole Shape from the Stock PCB + G4SubtractionSolid* PCB_1 = new G4SubtractionSolid("PCB_1", PCBFull, HoleShape, + new G4RotationMatrix,HoleShift1); + G4SubtractionSolid* PCB = new G4SubtractionSolid("PCB", PCB_1, HoleShape, + new G4RotationMatrix,HoleShift2); + + // Sub Volume PCB + G4LogicalVolume* logicPCB = + new G4LogicalVolume(PCB,m_MaterialPCB,"logicPCB", 0, 0, 0); + logicPCB->SetVisAttributes(PCBVisAtt); + + new G4PVPlacement(new G4RotationMatrix(0,0,0), + G4ThreeVector(0,0,0), + logicPCB,"Strasse_Outer_PCB",m_OuterDetector, + false,0); + + // Sub volume Wafer + G4Box* WaferShape = new G4Box("WaferShape", + Outer_Wafer_Width*0.5, + Outer_Wafer_Thickness*0.5+Outer_Wafer_AlThickness, + Outer_Wafer_Length*0.5); + + G4LogicalVolume* logicWafer1 = + new G4LogicalVolume(WaferShape,m_MaterialSilicon,"logicWafer1", 0, 0, 0); + logicWafer1->SetVisAttributes(GuardRingVisAtt); + + G4LogicalVolume* logicWafer2 = + new G4LogicalVolume(WaferShape,m_MaterialSilicon,"logicWafer2", 0, 0, 0); + logicWafer2->SetVisAttributes(GuardRingVisAtt); + + + new G4PVPlacement(new G4RotationMatrix(0,0,0), + G4ThreeVector(0,0.5*Outer_Wafer_Thickness + +Outer_Wafer_AlThickness + -0.5*Outer_PCB_Thickness,0)// flush the wafer to the pcb on one side + +HoleShift1, // Shift wafer in the hole + logicWafer1,"Strasse_Outer_Wafer1",m_OuterDetector, + false,0); + + new G4PVPlacement(new G4RotationMatrix(0,0,0), + G4ThreeVector(0,0.5*Outer_Wafer_Thickness + +Outer_Wafer_AlThickness + -0.5*Outer_PCB_Thickness,0)// flush the wafer to the pcb on one side + +HoleShift2, // Shift wafer in the hole + logicWafer2,"Strasse_Outer_Wafer2",m_OuterDetector, + false,0); + + // Sub volume Active Wafer + G4Box* ActiveWaferShape = new G4Box("OuterActiveWaferShape", + 0.5*m_Active_OuterWafer_Width, + 0.5*Outer_Wafer_Thickness, + 0.5*m_Active_OuterWafer_Length); + + G4LogicalVolume* logicActiveWafer1 = + new G4LogicalVolume(ActiveWaferShape,m_MaterialSilicon,"logicActiveWafer1", 0, 0, 0); + logicActiveWafer1->SetVisAttributes(SiliconVisAtt); + logicActiveWafer1->SetSensitiveDetector(m_OuterScorer1); + + G4LogicalVolume* logicActiveWafer2 = + new G4LogicalVolume(ActiveWaferShape,m_MaterialSilicon,"logicActiveWafer2", 0, 0, 0); + logicActiveWafer2->SetVisAttributes(SiliconVisAtt); + logicActiveWafer2->SetSensitiveDetector(m_OuterScorer2); + + + new G4PVPlacement(new G4RotationMatrix(0,0,0), + G4ThreeVector(0,0,0.5*(Outer_Wafer_PADExternal-Outer_Wafer_PADInternal)), // assymetric pading for bounding + logicActiveWafer1,"Strasse_Outer_ActiveWafer1",logicWafer1, + false,1); + + new G4PVPlacement(new G4RotationMatrix(0,0,0), + G4ThreeVector(0,0,-0.5*(Outer_Wafer_PADExternal-Outer_Wafer_PADInternal)), // assymetric pading for bounding + logicActiveWafer2,"Strasse_Outer_ActiveWafer2",logicWafer2, + false,2); + } + return m_OuterDetector; +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +G4LogicalVolume* Strasse::BuildChamber(){ + if(!m_Chamber){ + // Needed Element + G4Material* Material = MaterialManager::getInstance()->GetMaterialFromLibrary("Al"); + G4RotationMatrix* Rot = new G4RotationMatrix(); + + // Main Cylinder + G4Tubs* Cylinder = new G4Tubs("StrasseCylinderVolume", + Chamber_Radius-Chamber_Thickness, + Chamber_Radius,Chamber_Cylinder_Length*0.5, + 0,360*deg); + // for substraction + G4Tubs* DummyCyl = new G4Tubs("StrasseDummyCylVolume", + 0, + Chamber_Sphere_Radius*1.1,Chamber_Cylinder_Length*0.5, + 0,360*deg); + + + // G4LogicalVolume* ChamberCyl = new G4LogicalVolume(Cyl,Material,"logic_Strasse_Chamber",0,0,0); + + // Entrance Flange + G4Tubs* Flange = new G4Tubs("StrasseFlangeVolume", + Chamber_Flange_Inner_Radius, + Chamber_Radius,1*cm, + 0,360*deg); + + // G4LogicalVolume* ChamberFlange = new G4LogicalVolume(Flange,Material,"logic_Strasse_Flange",0,0,0); + + // Spherial Portion + G4Sphere* Sphere= new G4Sphere("StrasseSphereVolume", + Chamber_Sphere_Radius-Chamber_Thickness, + Chamber_Sphere_Radius, + 0,360*deg, + 0,180*deg); + + // Exit tube portion + G4Tubs* Tube = new G4Tubs("StrasseTubeVolume", + Chamber_ExitTube_Radius-Chamber_Thickness, + Chamber_ExitTube_Radius,Chamber_ExitTube_Length*0.5, + 0,360*deg); + G4Tubs* DummyTube = new G4Tubs("StrasseDummyTubeVolume", + 0, + Chamber_ExitTube_Radius*0.99,Chamber_ExitTube_Length*0.5, + 0,360*deg); + + //Partial Sphere + + G4SubtractionSolid* Sphere1= new G4SubtractionSolid("Sphere1",Sphere,DummyCyl, + Rot,G4ThreeVector(0,0,-Chamber_Sphere_Shift)); + G4SubtractionSolid* Sphere2= new G4SubtractionSolid("Sphere2",Sphere1,DummyTube, + Rot,G4ThreeVector(0,0,Chamber_Sphere_Radius+Chamber_ExitTube_Length*0.5-2*cm)); + + // Building the whole chamber + G4UnionSolid* Chamber1= new G4UnionSolid("Chamber1",Cylinder,Flange, + Rot,G4ThreeVector(0,0,-Chamber_Cylinder_Length*0.5)); + + G4UnionSolid* Chamber2= new G4UnionSolid("Chamber2",Chamber1,Sphere2, + Rot,G4ThreeVector(0,0,Chamber_Sphere_Shift)); + + G4UnionSolid* Chamber3= new G4UnionSolid("Chamber3",Chamber2,Tube, + Rot,G4ThreeVector(0,0,Chamber_Sphere_Shift+Chamber_Sphere_Radius+Chamber_ExitTube_Length*0.5-2*cm)); + + m_Chamber = new G4LogicalVolume(Chamber3,Material,"logic_Strasse_Chamber",0,0,0); + + + m_Chamber->SetVisAttributes(ChamberVisAtt); + } + + + return m_Chamber; + +} + +//....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 Strasse::ReadConfiguration(NPL::InputParser parser){ + // Info block + vector<NPL::InputBlock*> blocks_info = parser.GetAllBlocksWithTokenAndValue("Strasse","Info"); + if(NPOptionManager::getInstance()->GetVerboseLevel()) + cout << "//// " << blocks_info.size() << " info block founds " << endl; + + if(blocks_info.size()>1){ + cout << "ERROR: can only accepte one info block, " << blocks_info.size() << " info block founds." << endl; + exit(1); + } + + vector<string> info = { + "Inner_Wafer_Length", + "Inner_Wafer_Width", + "Inner_Wafer_Thickness", + "Inner_Wafer_AlThickness", + "Inner_Wafer_PADExternal", + "Inner_Wafer_PADInternal", + "Inner_Wafer_GuardRing", + "Inner_PCB_PortWidth", + "Inner_PCB_StarboardWidth", + "Inner_PCB_BevelAngle", + "Inner_PCB_UpstreamWidth", + "Inner_PCB_DownstreamWidth", + "Inner_PCB_MidWidth", + "Inner_PCB_Thickness", + "Inner_Wafer_TransverseStrips", + "Inner_Wafer_LongitudinalStrips", + "Outer_Wafer_Length", + "Outer_Wafer_Width", + "Outer_Wafer_Thickness", + "Outer_Wafer_AlThickness", + "Outer_Wafer_PADExternal", + "Outer_Wafer_PADInternal", + "Outer_Wafer_GuardRing", + "Outer_PCB_PortWidth", + "Outer_PCB_StarboardWidth", + "Outer_PCB_BevelAngle", + "Outer_PCB_UpstreamWidth", + "Outer_PCB_DownstreamWidth", + "Outer_PCB_MidWidth", + "Outer_PCB_Thickness", + "Outer_Wafer_TransverseStrips", + "Outer_Wafer_LongitudinalStrips", + "Chamber_Thickness", + "Chamber_Cylinder_Length", + "Chamber_Radius", + "Chamber_ExitTube_Radius", + "Chamber_ExitTube_Length", + "Chamber_Flange_Inner_Radius", + "Chamber_Sphere_Radius", + "Chamber_Sphere_Shift" + }; + + if(blocks_info[0]->HasTokenList(info)){ + cout << endl << "//// Strasse info block" << endl; + Inner_Wafer_Length = blocks_info[0]->GetDouble("Inner_Wafer_Length","mm"); + Inner_Wafer_Width = blocks_info[0]->GetDouble("Inner_Wafer_Width","mm"); + Inner_Wafer_Thickness = blocks_info[0]->GetDouble("Inner_Wafer_Thickness","micrometer"); + Inner_Wafer_AlThickness = blocks_info[0]->GetDouble("Inner_Wafer_AlThickness","micrometer"); + Inner_Wafer_PADExternal = blocks_info[0]->GetDouble("Inner_Wafer_PADExternal","mm"); + Inner_Wafer_PADInternal = blocks_info[0]->GetDouble("Inner_Wafer_PADInternal","mm"); + Inner_Wafer_GuardRing = blocks_info[0]->GetDouble("Inner_Wafer_GuardRing","mm"); + Inner_Wafer_TransverseStrips = blocks_info[0]->GetInt("Inner_Wafer_TransverseStrips"); + Inner_Wafer_LongitudinalStrips = blocks_info[0]->GetInt("Inner_Wafer_LongitudinalStrips"); + Inner_PCB_PortWidth = blocks_info[0]->GetDouble("Inner_PCB_PortWidth","mm"); + Inner_PCB_StarboardWidth = blocks_info[0]->GetDouble("Inner_PCB_StarboardWidth","mm"); + Inner_PCB_BevelAngle = blocks_info[0]->GetDouble("Inner_PCB_BevelAngle","mm"); + Inner_PCB_UpstreamWidth = blocks_info[0]->GetDouble("Inner_PCB_UpstreamWidth","mm"); + Inner_PCB_DownstreamWidth = blocks_info[0]->GetDouble("Inner_PCB_DownstreamWidth","mm"); + Inner_PCB_MidWidth = blocks_info[0]->GetDouble("Inner_PCB_MidWidth","mm"); + Inner_PCB_Thickness = blocks_info[0]->GetDouble("Inner_PCB_Thickness","mm"); + Outer_Wafer_Length = blocks_info[0]->GetDouble("Outer_Wafer_Length","mm"); + Outer_Wafer_Width = blocks_info[0]->GetDouble("Outer_Wafer_Width","mm"); + Outer_Wafer_Thickness = blocks_info[0]->GetDouble("Outer_Wafer_Thickness","mm"); + Outer_Wafer_AlThickness = blocks_info[0]->GetDouble("Outer_Wafer_AlThickness","micrometer"); + Outer_Wafer_PADExternal = blocks_info[0]->GetDouble("Outer_Wafer_PADExternal","mm"); + Outer_Wafer_PADInternal = blocks_info[0]->GetDouble("Outer_Wafer_PADInternal","mm"); + Outer_Wafer_GuardRing = blocks_info[0]->GetDouble("Outer_Wafer_GuardRing","mm"); + Outer_Wafer_TransverseStrips = blocks_info[0]->GetInt("Outer_Wafer_TransverseStrips"); + Outer_Wafer_LongitudinalStrips = blocks_info[0]->GetInt("Outer_Wafer_LongitudinalStrips"); + Outer_PCB_PortWidth = blocks_info[0]->GetDouble("Outer_PCB_PortWidth","mm"); + Outer_PCB_StarboardWidth = blocks_info[0]->GetDouble("Outer_PCB_StarboardWidth","mm"); + Outer_PCB_BevelAngle = blocks_info[0]->GetDouble("Outer_PCB_BevelAngle","deg"); + Outer_PCB_UpstreamWidth = blocks_info[0]->GetDouble("Outer_PCB_UpstreamWidth","mm"); + Outer_PCB_DownstreamWidth = blocks_info[0]->GetDouble("Outer_PCB_DownstreamWidth","mm"); + Outer_PCB_MidWidth = blocks_info[0]->GetDouble("Outer_PCB_MidWidth","mm"); + Outer_PCB_Thickness = blocks_info[0]->GetDouble("Outer_PCB_Thickness","mm"); + Chamber_Thickness= blocks_info[0]->GetDouble("Chamber_Thickness","mm"); + Chamber_Cylinder_Length= blocks_info[0]->GetDouble("Chamber_Cylinder_Length","mm"); + Chamber_Radius= blocks_info[0]->GetDouble("Chamber_Radius","mm"); + Chamber_ExitTube_Radius=blocks_info[0]->GetDouble("Chamber_ExitTube_Radius","mm"); + Chamber_ExitTube_Length=blocks_info[0]->GetDouble("Chamber_ExitTube_Length","mm"); + Chamber_Flange_Inner_Radius=blocks_info[0]->GetDouble("Chamber_Flange_Inner_Radius","mm"); + Chamber_Sphere_Radius=blocks_info[0]->GetDouble("Chamber_Sphere_Radius","mm"); + Chamber_Sphere_Shift=blocks_info[0]->GetDouble("Chamber_Sphere_Shift","mm"); + } + + else{ + cout << "ERROR: check your input file formatting " << endl; + exit(1); + } + + + // Inner Barrel + vector<NPL::InputBlock*> blocks_inner = parser.GetAllBlocksWithTokenAndValue("Strasse","Inner"); + if(NPOptionManager::getInstance()->GetVerboseLevel()) + cout << "//// " << blocks_inner.size() << " inner detectors found " << endl; + + vector<string> coord = {"Radius","Z","Phi","Shift","Ref"}; + + for(unsigned int i = 0 ; i < blocks_inner.size() ; i++){ + if(blocks_inner[i]->HasTokenList(coord)){ + if(NPOptionManager::getInstance()->GetVerboseLevel()) + cout << endl << "//// Strasse inner detector" << i+1 << endl; + + double R = blocks_inner[i]->GetDouble("Radius","mm"); + double Z= blocks_inner[i]->GetDouble("Z","mm"); + double Phi = blocks_inner[i]->GetDouble("Phi","deg"); + double Shift = blocks_inner[i]->GetDouble("Shift","mm"); + G4ThreeVector Ref = NPS::ConvertVector(blocks_inner[i]->GetTVector3("Ref","mm")); + AddInnerDetector(R,Z,Phi,Shift,Ref); + } + else{ + cout << "ERROR: check your input file formatting on " << i+1 << " inner block " <<endl; + exit(1); + } + } + + // Outer barrel + vector<NPL::InputBlock*> blocks_outer = parser.GetAllBlocksWithTokenAndValue("Strasse","Outer"); + if(NPOptionManager::getInstance()->GetVerboseLevel()) + cout << "//// " << blocks_outer.size() << " outer detectors found " << endl; + + for(unsigned int i = 0 ; i < blocks_outer.size() ; i++){ + if(blocks_outer[i]->HasTokenList(coord)){ + if(NPOptionManager::getInstance()->GetVerboseLevel()) + cout << endl << "//// Strasse outer detector" << i+1 << endl; + + double R = blocks_outer[i]->GetDouble("Radius","mm"); + double Z= blocks_outer[i]->GetDouble("Z","mm"); + double Phi = blocks_outer[i]->GetDouble("Phi","deg"); + double Shift = blocks_outer[i]->GetDouble("Shift","mm"); + G4ThreeVector Ref = NPS::ConvertVector(blocks_inner[i]->GetTVector3("Ref","mm")); + AddOuterDetector(R,Z,Phi,Shift,Ref); + } + else{ + + cout << "ERROR: check your input file formatting on " << i+1 << " outer block " <<endl; + exit(1); + } + } + + // Chamber + vector<std::string> token = {"Z"}; + vector<NPL::InputBlock*> blocks_chamber = parser.GetAllBlocksWithTokenAndValue("Strasse","Chamber"); + if(NPOptionManager::getInstance()->GetVerboseLevel()) + cout << "//// " << blocks_chamber.size() << " chamber detectors found " << endl; + + for(unsigned int i = 0 ; i < blocks_chamber.size() ; i++){ + if(blocks_chamber[i]->HasTokenList(token)){ + if(NPOptionManager::getInstance()->GetVerboseLevel()) + cout << endl << "//// Strasse chamber detector" << i+1 << endl; + + double Z= blocks_chamber[i]->GetDouble("Z","mm"); + AddChamber(Z); + } + else{ + + cout << "ERROR: check your input file formatting on " << i+1 << " chamber block " <<endl; + exit(1); + } + } + + +} + + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... + +// Construct detector and inialise sensitive part. +// Called After DetecorConstruction::AddDetector Method +void Strasse::ConstructDetector(G4LogicalVolume* world){ + + // Inner Barrel + for (unsigned short i = 0 ; i < m_Inner_R.size() ; i++) { + G4ThreeVector Det_pos = G4ThreeVector(m_Inner_Shift[i],m_Inner_R[i]+0.5*Inner_PCB_Thickness,m_Inner_Z[i]) ; + Det_pos.rotate(-m_Inner_Phi[i],G4ThreeVector(0,0,1)); + G4RotationMatrix* Rot = new G4RotationMatrix(0*deg,0*deg,m_Inner_Phi[i]); + + new G4PVPlacement(G4Transform3D(*Rot,Det_pos+m_Inner_Ref[i]), + BuildInnerDetector(), + "Strasse",world,false,i+1); + } + + // Outer Barrel + for (unsigned short i = 0 ; i < m_Outer_R.size() ; i++) { + G4ThreeVector Det_pos = G4ThreeVector(m_Outer_Shift[i],m_Outer_R[i]+0.5*Inner_PCB_Thickness,m_Outer_Z[i]) ; + Det_pos.rotate(-m_Outer_Phi[i],G4ThreeVector(0,0,1)); + G4RotationMatrix* Rot = new G4RotationMatrix(0*deg,0*deg,m_Outer_Phi[i]); + + new G4PVPlacement(G4Transform3D(*Rot,Det_pos+m_Outer_Ref[i]), + BuildOuterDetector(), + "Strasse",world,false,i+1); + } + + // Chamber + for (unsigned short i = 0 ; i < m_Chamber_Z.size() ; i++) { + G4ThreeVector Det_pos = G4ThreeVector(0,0,-m_Chamber_Z[i]) ; + G4RotationMatrix* Rot = new G4RotationMatrix(); + + new G4PVPlacement(G4Transform3D(*Rot,Det_pos), + BuildChamber(), + "Strasse",world,false,i+1); + } +} +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +// Add Detector branch to the EventTree. +// Called After DetecorConstruction::AddDetector Method +void Strasse::InitializeRootOutput(){ + RootOutput *pAnalysis = RootOutput::getInstance(); + TTree *pTree = pAnalysis->GetTree(); + if(!pTree->FindBranch("Strasse")){ + pTree->Branch("Strasse", "TStrasseData", &m_Event) ; + } + pTree->SetBranchAddress("Strasse", &m_Event) ; +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +// Read sensitive part and fill the Root tree. +// Called at in the EventAction::EndOfEventAvtion +void Strasse::ReadSensitive(const G4Event* ){ + m_Event->Clear(); + + /////////// + // Inner barrel scorer + DSSDScorers::PS_Rectangle* InnerScorer1= (DSSDScorers::PS_Rectangle*) m_InnerScorer1->GetPrimitive(0); + + unsigned int size = InnerScorer1->GetWidthMult(); + for(unsigned int i = 0 ; i < size; i++){ + double Energy = RandGauss::shoot(InnerScorer1->GetEnergyWidth(i), ResoEnergy); + if(Energy>EnergyThreshold){ + int DetNbr = InnerScorer1->GetDetectorWidth(i); + int StripTransverse = InnerScorer1->GetStripWidth(i); + m_Event->SetInnerTE(DetNbr, StripTransverse, Energy); + } + } + + size = InnerScorer1->GetLengthMult(); + for(unsigned int i = 0 ; i < size ; i++){ + double Energy = RandGauss::shoot(InnerScorer1->GetEnergyLength(i), ResoEnergy); + if(Energy>EnergyThreshold){ + int DetNbr = InnerScorer1->GetDetectorLength(i); + int StripLongitudinal= InnerScorer1->GetStripLength(i); + m_Event->SetInnerLE(DetNbr, StripLongitudinal, Energy); + } + } + InnerScorer1->clear(); + + // second silicon + DSSDScorers::PS_Rectangle* InnerScorer2= (DSSDScorers::PS_Rectangle*) m_InnerScorer2->GetPrimitive(0); + + size = InnerScorer2->GetWidthMult(); + for(unsigned int i = 0 ; i < size; i++){ + double Energy = RandGauss::shoot(InnerScorer2->GetEnergyWidth(i), ResoEnergy); + if(Energy>EnergyThreshold){ + int DetNbr = InnerScorer2->GetDetectorWidth(i); + int StripTransverse = InnerScorer2->GetStripWidth(i)+Inner_Wafer_TransverseStrips; + m_Event->SetInnerTE(DetNbr, StripTransverse, Energy); + } + } + size = InnerScorer2->GetLengthMult(); + for(unsigned int i = 0 ; i < size ; i++){ + double Energy = RandGauss::shoot(InnerScorer2->GetEnergyLength(i), ResoEnergy); + if(Energy>EnergyThreshold){ + int DetNbr = InnerScorer2->GetDetectorLength(i); + int StripLongitudinal= InnerScorer2->GetStripLength(i); + m_Event->SetInnerLE(DetNbr, StripLongitudinal, Energy); + } + } + InnerScorer2->clear(); + + + + /////////// + // Outer barrel scorer + DSSDScorers::PS_Rectangle* OuterScorer1= (DSSDScorers::PS_Rectangle*) m_OuterScorer1->GetPrimitive(0); + + size = OuterScorer1->GetWidthMult(); + for(unsigned int i = 0 ; i < size; i++){ + double Energy = RandGauss::shoot(OuterScorer1->GetEnergyWidth(i), ResoEnergy); + if(Energy>EnergyThreshold){ + int DetNbr = OuterScorer1->GetDetectorWidth(i); + int StripTransverse = OuterScorer1->GetStripWidth(i); + m_Event->SetOuterTE(DetNbr, StripTransverse, Energy); + } + } + size = OuterScorer1->GetLengthMult(); + for(unsigned int i = 0 ; i < size ; i++){ + double Energy = RandGauss::shoot(OuterScorer1->GetEnergyLength(i), ResoEnergy); + if(Energy>EnergyThreshold){ + int DetNbr = OuterScorer1->GetDetectorLength(i); + int StripLongitudinal= OuterScorer1->GetStripLength(i); + m_Event->SetOuterLE(DetNbr, StripLongitudinal, Energy); + } + } + OuterScorer1->clear(); + + // Second silicon + DSSDScorers::PS_Rectangle* OuterScorer2= (DSSDScorers::PS_Rectangle*) m_OuterScorer2->GetPrimitive(0); + + size = OuterScorer2->GetWidthMult(); + for(unsigned int i = 0 ; i < size; i++){ + double Energy = RandGauss::shoot(OuterScorer2->GetEnergyWidth(i), ResoEnergy); + if(Energy>EnergyThreshold){ + int DetNbr = OuterScorer2->GetDetectorWidth(i); + int StripTransverse = OuterScorer2->GetStripWidth(i)+Outer_Wafer_TransverseStrips; + m_Event->SetOuterTE(DetNbr, StripTransverse, Energy); + } + } + size = OuterScorer2->GetLengthMult(); + for(unsigned int i = 0 ; i < size ; i++){ + double Energy = RandGauss::shoot(OuterScorer2->GetEnergyLength(i), ResoEnergy); + if(Energy>EnergyThreshold){ + int DetNbr = OuterScorer2->GetDetectorLength(i); + int StripLongitudinal= OuterScorer2->GetStripLength(i); + m_Event->SetOuterLE(DetNbr, StripLongitudinal, Energy); + } + } + OuterScorer2->clear(); + + +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//////////////////////////////////////////////////////////////// +void Strasse::InitializeScorers() { + // This check is necessary in case the geometry is reloaded + bool already_exist = false; + m_InnerScorer1 = CheckScorer("InnerScorer1",already_exist) ; + m_OuterScorer1 = CheckScorer("OuterScorer1",already_exist) ; + m_InnerScorer2 = CheckScorer("InnerScorer2",already_exist) ; + m_OuterScorer2 = CheckScorer("OuterScorer2",already_exist) ; + + if(already_exist) + return ; + + // Otherwise the scorer is initialised + m_Active_InnerWafer_Width= Inner_Wafer_Width-2.*Inner_Wafer_GuardRing; + m_Active_InnerWafer_Length= + Inner_Wafer_Length-Inner_Wafer_PADExternal-Inner_Wafer_PADInternal-2*Inner_Wafer_GuardRing; + + + G4VPrimitiveScorer* InnerScorer1 = new DSSDScorers::PS_Rectangle("InnerScorer1",2, + m_Active_InnerWafer_Width, + m_Active_InnerWafer_Length, + Inner_Wafer_LongitudinalStrips, + Inner_Wafer_TransverseStrips,0,"xz"); + + G4VPrimitiveScorer* InnerScorer2 = new DSSDScorers::PS_Rectangle("InnerScorer2",2, + m_Active_InnerWafer_Width, + m_Active_InnerWafer_Length, + Inner_Wafer_LongitudinalStrips, + Inner_Wafer_TransverseStrips,0,"xz"); + + + m_Active_OuterWafer_Width=Outer_Wafer_Width-2.*Outer_Wafer_GuardRing; + m_Active_OuterWafer_Length= + Outer_Wafer_Length-Outer_Wafer_PADExternal-Outer_Wafer_PADInternal-2*Outer_Wafer_GuardRing; + + + G4VPrimitiveScorer* OuterScorer1 = new DSSDScorers::PS_Rectangle("OuterScorer1",2, + m_Active_OuterWafer_Width, + m_Active_OuterWafer_Length, + Outer_Wafer_LongitudinalStrips, + Outer_Wafer_TransverseStrips,0,"xz"); + + G4VPrimitiveScorer* OuterScorer2 = new DSSDScorers::PS_Rectangle("OuterScorer2",2, + m_Active_OuterWafer_Width, + m_Active_OuterWafer_Length, + Outer_Wafer_LongitudinalStrips, + Outer_Wafer_TransverseStrips,0,"xz"); + + + + G4VPrimitiveScorer* InteractionInner1 = new InteractionScorers::PS_Interactions("InteractionInner1",ms_InterCoord,0); + G4VPrimitiveScorer* InteractionOuter1 = new InteractionScorers::PS_Interactions("InteractionOuter1",ms_InterCoord,0); + G4VPrimitiveScorer* InteractionInner2 = new InteractionScorers::PS_Interactions("InteractionInner2",ms_InterCoord,0); + G4VPrimitiveScorer* InteractionOuter2 = new InteractionScorers::PS_Interactions("InteractionOuter2",ms_InterCoord,0); + + + // Register it to the multifunctionnal detector + m_InnerScorer1->RegisterPrimitive(InnerScorer1); + m_InnerScorer1->RegisterPrimitive(InteractionInner1); + m_OuterScorer1->RegisterPrimitive(OuterScorer1); + m_OuterScorer1->RegisterPrimitive(InteractionOuter1); + m_InnerScorer2->RegisterPrimitive(InnerScorer2); + m_InnerScorer2->RegisterPrimitive(InteractionInner2); + m_OuterScorer2->RegisterPrimitive(OuterScorer2); + m_OuterScorer2->RegisterPrimitive(InteractionOuter2); + + + G4SDManager::GetSDMpointer()->AddNewDetector(m_InnerScorer1); + G4SDManager::GetSDMpointer()->AddNewDetector(m_OuterScorer1); + G4SDManager::GetSDMpointer()->AddNewDetector(m_InnerScorer2); + G4SDManager::GetSDMpointer()->AddNewDetector(m_OuterScorer2); + + +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//////////////////////////////////////////////////////////////////////////////// +// Construct Method to be pass to the DetectorFactory // +//////////////////////////////////////////////////////////////////////////////// +NPS::VDetector* Strasse::Construct(){ + return (NPS::VDetector*) new Strasse(); +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +void Strasse::InitializeMaterial(){ + m_MaterialSilicon = MaterialManager::getInstance()->GetMaterialFromLibrary("Si"); + m_MaterialAl = MaterialManager::getInstance()->GetMaterialFromLibrary("Al"); + m_MaterialPCB = MaterialManager::getInstance()->GetMaterialFromLibrary("PCB"); + m_MaterialVacuum = MaterialManager::getInstance()->GetMaterialFromLibrary("Vacuum"); +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//////////////////////////////////////////////////////////////////////////////// +// Registering the construct method to the factory // +//////////////////////////////////////////////////////////////////////////////// +extern"C" { + class proxy_nps_Strasse{ + public: + proxy_nps_Strasse(){ + NPS::DetectorFactory::getInstance()->AddToken("Strasse","Strasse"); + NPS::DetectorFactory::getInstance()->AddDetector("Strasse",Strasse::Construct); + } + }; + + proxy_nps_Strasse p_nps_Strasse; +} + + diff --git a/NPSimulation/Detectors/Strasse/Strasse.hh b/NPSimulation/Detectors/Strasse/Strasse.hh new file mode 100644 index 0000000000000000000000000000000000000000..f2012f6ee502b60b8c250f8b7a2c858450866c8a --- /dev/null +++ b/NPSimulation/Detectors/Strasse/Strasse.hh @@ -0,0 +1,162 @@ +#ifndef Strasse_h +#define Strasse_h 1 +/***************************************************************************** + * Copyright (C) 2009-2020 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: A. Matta contact address: matta@lpccaen.in2p3.fr * + * * + * Creation Date : July 2020 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class describe Strasse 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 "TStrasseData.h" +#include "NPInputParser.h" + +class Strasse : public NPS::VDetector{ + //////////////////////////////////////////////////// + /////// Default Constructor and Destructor ///////// + //////////////////////////////////////////////////// + public: + Strasse() ; + virtual ~Strasse() ; + + //////////////////////////////////////////////////// + /////// Specific Function of this Class /////////// + //////////////////////////////////////////////////// + public: + // Cylindrical coordinate + void AddInnerDetector(double R,double Z,double Phi, double Shift, G4ThreeVector Ref); + void AddOuterDetector(double R,double Z,double Phi, double Shift, G4ThreeVector Ref); + void AddChamber(double Z); + + G4LogicalVolume* BuildInnerDetector(); + G4LogicalVolume* BuildOuterDetector(); + G4LogicalVolume* BuildElectronic(); + G4LogicalVolume* BuildFrame(); + G4LogicalVolume* BuildChamber(); + + private: + G4LogicalVolume* m_InnerDetector; + G4LogicalVolume* m_OuterDetector; + G4LogicalVolume* m_Electronic; + G4LogicalVolume* m_Frame; + G4LogicalVolume* m_Chamber; + + + private: + // Initialize material used in detector definition + void InitializeMaterial(); + + + // List of material + G4Material* m_MaterialSilicon ; + G4Material* m_MaterialAl ; + G4Material* m_MaterialVacuum ; + G4Material* m_MaterialPCB ; + + // calculated dimension + double m_Active_InnerWafer_Width; + double m_Active_InnerWafer_Length; + double m_Active_OuterWafer_Width; + double m_Active_OuterWafer_Length; + + + //////////////////////////////////////////////////// + ////// 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_InnerScorer1 ; + G4MultiFunctionalDetector* m_OuterScorer1 ; + G4MultiFunctionalDetector* m_InnerScorer2 ; + G4MultiFunctionalDetector* m_OuterScorer2 ; + + //////////////////////////////////////////////////// + ///////////Event class to store Data//////////////// + //////////////////////////////////////////////////// + private: + TStrasseData* m_Event ; + + //////////////////////////////////////////////////// + ///////////////Private intern Data////////////////// + //////////////////////////////////////////////////// + private: // Geometry + // Detector Coordinate + vector<double> m_Inner_R; + vector<double> m_Inner_Z; + vector<double> m_Inner_Phi; + vector<double> m_Inner_Shift; + vector<G4ThreeVector> m_Inner_Ref; + + vector<double> m_Outer_R; + vector<double> m_Outer_Z; + vector<double> m_Outer_Phi; + vector<double> m_Outer_Shift; + vector<G4ThreeVector> m_Outer_Ref; + + vector<double> m_Chamber_Z; + + // Visualisation Attribute + //G4VisAttributes* m_VisTrap; + + // Needed for dynamic loading of the library + public: + static NPS::VDetector* Construct(); + + + private: // Visualisation + G4VisAttributes* SiliconVisAtt ; + G4VisAttributes* PCBVisAtt; + G4VisAttributes* PADVisAtt ; + G4VisAttributes* FrameVisAtt ; + G4VisAttributes* ChamberVisAtt ; + G4VisAttributes* GuardRingVisAtt ; + + +}; +#endif diff --git a/NPSimulation/Detectors/TACTIC/18Ne21Na.reaction b/NPSimulation/Detectors/TACTIC/18Ne21Na.reaction new file mode 100644 index 0000000000000000000000000000000000000000..f5dd72e2c15e8751e768224de2f6ffba58d92a32 --- /dev/null +++ b/NPSimulation/Detectors/TACTIC/18Ne21Na.reaction @@ -0,0 +1,28 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%% Reaction file for 18Ne(alpha,p)21Na reaction %%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Beam + Particle= 18Ne + Energy= 50 MeV + SigmaEnergy= 0 MeV + SigmaX= 1 mm + SigmaY= 1 mm + SigmaThetaX= 0 deg + SigmaPhiY= 0 deg + MeanThetaX= 0 deg + MeanPhiY= 0 deg + MeanX= 0 mm + MeanY= 0 mm + +TwoBodyReaction + Beam= 18Ne + Target= 4He + Light= 1H + Heavy= 21Na + ExcitationEnergyHeavy= 0.0 + ExcitationEnergyLight= 0.0 + CrossSectionPath= flat.txt CS + ShootLight= 1 + ShootHeavy= 1 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + diff --git a/NPSimulation/Detectors/TACTIC/18Ne4He_scat.reaction b/NPSimulation/Detectors/TACTIC/18Ne4He_scat.reaction new file mode 100644 index 0000000000000000000000000000000000000000..e7bb1cddc0dfe42d07cfbc50b8e2142d515281db --- /dev/null +++ b/NPSimulation/Detectors/TACTIC/18Ne4He_scat.reaction @@ -0,0 +1,28 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%% Reaction file for 18Ne4He elastic scattering %%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Beam + Particle= 18Ne + Energy= 15 MeV + SigmaEnergy= 0 MeV + SigmaX= 1 mm + SigmaY= 1 mm + SigmaThetaX= 0 deg + SigmaPhiY= 0 deg + MeanThetaX= 0 deg + MeanPhiY= 0 deg + MeanX= 0 mm + MeanY= 0 mm + +TwoBodyReaction + Beam= 18Ne + Target= 4He + Light= 4He + Heavy= 18Ne + ExcitationEnergyHeavy= 0.0 + ExcitationEnergyLight= 0.0 + CrossSectionPath= flat.txt CS + ShootLight= 1 + ShootHeavy= 1 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + diff --git a/NPSimulation/Detectors/TACTIC/8Li11B.reaction b/NPSimulation/Detectors/TACTIC/8Li11B.reaction new file mode 100644 index 0000000000000000000000000000000000000000..5b5e226ee18e7bac48a5f4c32cd0c1eb50f49cf5 --- /dev/null +++ b/NPSimulation/Detectors/TACTIC/8Li11B.reaction @@ -0,0 +1,28 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%% Reaction file for 18Ne(alpha,p)21Na reaction %%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Beam + Particle= 8Li + Energy= 15 MeV + SigmaEnergy= 0 MeV + SigmaX= 1 mm + SigmaY= 1 mm + SigmaThetaX= 0 deg + SigmaPhiY= 0 deg + MeanThetaX= 0 deg + MeanPhiY= 0 deg + MeanX= 0 mm + MeanY= 0 mm + +TwoBodyReaction + Beam= 8Li + Target= 4He + Light= neutron + Heavy= 11B + ExcitationEnergyHeavy= 0.0 + ExcitationEnergyLight= 0.0 + CrossSectionPath= flat.txt CS + ShootLight= 1 + ShootHeavy= 1 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + diff --git a/NPSimulation/Detectors/TACTIC/8Li4He_scat.reaction b/NPSimulation/Detectors/TACTIC/8Li4He_scat.reaction new file mode 100644 index 0000000000000000000000000000000000000000..ec9a2bba6ebb8b1a09e868735426427b61efc21d --- /dev/null +++ b/NPSimulation/Detectors/TACTIC/8Li4He_scat.reaction @@ -0,0 +1,28 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%% Reaction file for 8Li11B scat %%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Beam + Particle= 8Li + Energy= 15 MeV + SigmaEnergy= 0 MeV + SigmaX= 1 mm + SigmaY= 1 mm + SigmaThetaX= 0 deg + SigmaPhiY= 0 deg + MeanThetaX= 0 deg + MeanPhiY= 0 deg + MeanX= 0 mm + MeanY= 0 mm + +TwoBodyReaction + Beam= 8Li + Target= 4He + Light= 4He + Heavy= 8Li + ExcitationEnergyHeavy= 0.0 + ExcitationEnergyLight= 0.0 + CrossSectionPath= flat.txt CS + ShootLight= 1 + ShootHeavy= 1 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + diff --git a/NPSimulation/Detectors/TACTIC/CMakeLists.txt b/NPSimulation/Detectors/TACTIC/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..0f45c9906bb8931667f8aaf54c2289da1dc66a2d --- /dev/null +++ b/NPSimulation/Detectors/TACTIC/CMakeLists.txt @@ -0,0 +1,2 @@ +add_library(NPSTACTIC SHARED TACTIC.cc TACTICScorer.cc) +target_link_libraries(NPSTACTIC NPSCore ${ROOT_LIBRARIES} ${Geant4_LIBRARIES} ${NPLib_LIBRARIES} -lNPTACTIC) diff --git a/NPSimulation/Detectors/TACTIC/README b/NPSimulation/Detectors/TACTIC/README new file mode 100644 index 0000000000000000000000000000000000000000..ed14cbab0992b9301c96d58323ebb826eb59747a --- /dev/null +++ b/NPSimulation/Detectors/TACTIC/README @@ -0,0 +1,51 @@ +out.dat contains the latest setp information after the particle in question has traversed the length of a strip (~4mm) for step size of (~0.1mm) + +The coloumn headings of out.dat are: + +Event ID +Track ID +Particle ID (see below for index list) +Time +Kinetic Energy +Ionization Energy Deposit (Accumilated during the particles traversal across the strip length) +Pad Number +z Position +R Position +Vertex Position +Vertex Kinetic Energy +Vertex Theta +Track Length + +(If there has not been a vertex during the step then the vertex information given is taken from the last vertex position) + +Particle Index list: + +0 Ne18 +1 Na21 +2 proton +3 alpha +4 Li8 +5 B11 +6 neutron (athough the chances of neutron scattering are almost negligable) + +The simulation is only currently set up for a Ne18 or Li8 beam. To include different beam species the species should be added to the partilce index list in TACTICScorer.cc + +To run: + +npsimulation -D TACTIC.detector -E 18Ne21Na.reaction + +for batch mode edit run.mac and run: npsimulation -D TACTIC.detector -E 18Ne21Na.reaction -B run.mac + +TACTIC.detector is the detector config file, the gas can be changed here between He/CO2 and P10 and the pressure, temperature etc. can be changed. If using P10 set P10 gas fraction to 100 and set another gas fration (CO2 for example) to zero (i.e the code looks for two gases). + +18Ne21Na_reaction is the reaction file. The beam energy, spread, etc. can be changed here. Other reactions currently available are: + +18Ne4He_scat.reaction +8Li11B.reaction +8Li4He_scat.reaction + +Other reaction files can be created but the particles involved will need to be added to the particle index in TACTICScorer.cc . + +The reactions are currently isotropic in both angle and energy distribution. + +IMPORTANT: The output will continue to append to out.dat so when starting a new run either delete or move the existing out.dat if you do not wish to append to the existing data file. diff --git a/NPSimulation/Detectors/TACTIC/TACTIC.cc b/NPSimulation/Detectors/TACTIC/TACTIC.cc new file mode 100644 index 0000000000000000000000000000000000000000..4c9a93d7777c432deecb07897515f3c5040b48e7 --- /dev/null +++ b/NPSimulation/Detectors/TACTIC/TACTIC.cc @@ -0,0 +1,375 @@ +/***************************************************************************** + * Copyright (C) 2009-2020 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: Warren Lynch contact address: Warren.Lynch@york.ac.uk * + * * + * Creation Date : June 2020 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class describe TACTIC 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" +#include "G4THitsMap.hh" +#include "G4SDParticleFilter.hh" + +// NPTool header +#include "TACTIC.hh" +#include "TACTICScorer.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 TACTIC_NS{ + // Energy and time Resolution + + //const double EnergyThreshold = 0.01*MeV; + //const double ResoTime = 17.*ns ; + //const double ResoEnergy = 1.0*MeV ; + const double cathode_radius = 12.*mm; + const double drift_radius = 50.*mm; + const double anode_radius = 51.*mm; + const double active_length = 251.9*mm; + const double window_pos = 104.*mm; //from centre of TACTIC from https://elog.triumf.ca/Tactic/Documentation/18 + const double window_radius = 12.*mm; //guess + const double window_width = 1.5e-03*mm; + const double vacuum_pos = (active_length/2. + window_pos + window_width/2.)/2.*mm; + const double vacuum_width = active_length/2. - window_pos - window_width/2.*mm; + const G4int NumberOfStrips = 60; + +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +// TACTIC Specific Method +TACTIC::TACTIC(){ + m_Event = new TTACTICData() ; + m_Scorer = 0; + m_CylindricalDetector = 0; + + m_ReactionRegion = NULL; + // RGB Color + Transparency + + m_VisChamber = new G4VisAttributes(G4Colour(1., 1., 1., 1.0)); + m_VisWindows = new G4VisAttributes(G4Colour(1, 1, 1, 1.0)); + m_VisGas = new G4VisAttributes(G4Colour(1, 1, 1, 0.1)); + m_VisVacuum = new G4VisAttributes(G4Colour(1,1,1,1.)); + + m_VisChamber->SetForceWireframe(true); + m_VisVacuum->SetForceWireframe(true); +} + +TACTIC::~TACTIC(){ +} +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +void TACTIC::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 TACTIC::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* TACTIC::BuildCylindricalDetector(){ + if(!m_CylindricalDetector){ + + G4Material* Cu = MaterialManager::getInstance()->GetMaterialFromLibrary("Cu"); + G4Material* Mylar = MaterialManager::getInstance()->GetMaterialFromLibrary("Mylar"); + G4Material* Vacuum = MaterialManager::getInstance()->GetMaterialFromLibrary("Vacuum"); + + unsigned const int NumberOfGasMix = m_GasMaterial.size(); + + double density=0; + vector<G4Material*> GasComponent; + + for(unsigned int i=0; i<NumberOfGasMix; i++){ + if(m_GasMaterial[i] == "CO2") GasComponent.push_back(MaterialManager::getInstance()->GetGasFromLibrary(m_GasMaterial[i], 1.0/bar, m_Temperature)); + else GasComponent.push_back(MaterialManager::getInstance()->GetMaterialFromLibrary(m_GasMaterial[i])); + } + + for(unsigned int i=0; i<NumberOfGasMix; i++){ + density += ((double)m_GasFraction[i]/100)*GasComponent[i]->GetDensity()*(m_Pressure/bar)/(GasComponent[i]->GetPressure()/bar); + // p2 = p1*(P2/P1) //e.g. p2 = p1*(0.5/1) p scales with P, T=const + } + + G4Material* TACTIC_gas = new G4Material("TACTIC_gas", density, NumberOfGasMix, kStateGas, m_Temperature, m_Pressure); + + for(unsigned int i=0; i<NumberOfGasMix; i++) TACTIC_gas->AddMaterial(GasComponent[i], (double)m_GasFraction[i]/100); + + cout << TACTIC_gas << endl; + + G4Tubs* anode = new G4Tubs("anode",0,TACTIC_NS::anode_radius,TACTIC_NS::active_length*0.5,0,360*deg); + G4Tubs* gas_volume = new G4Tubs("gas_volume",0,TACTIC_NS::drift_radius,TACTIC_NS::active_length*0.5,0,360*deg); + G4Tubs* window = new G4Tubs("window",0,TACTIC_NS::window_radius,TACTIC_NS::window_width*0.5,0,360*deg); + G4Tubs* vacuum = new G4Tubs("vacuum",0,TACTIC_NS::window_radius,TACTIC_NS::vacuum_width*0.5,0,360*deg); + + m_CylindricalDetector = new G4LogicalVolume(anode, Cu, "anode_log",0,0,0); + gas_volume_log = new G4LogicalVolume(gas_volume, TACTIC_gas, "gas_volume_log",0,0,0); + window_log = new G4LogicalVolume(window, Mylar, "window_log",0,0,0); + vacuum_log = new G4LogicalVolume(vacuum, Vacuum, "vacuum_log",0,0,0); + + new G4PVPlacement(0,G4ThreeVector(0,0,0),gas_volume_log,"gas_volume_phys",m_CylindricalDetector,false,0); + new G4PVPlacement(0,G4ThreeVector(0,0,TACTIC_NS::window_pos),window_log,"window_phys",gas_volume_log,false,0); + new G4PVPlacement(0,G4ThreeVector(0,0,-TACTIC_NS::window_pos),window_log,"window_phys",gas_volume_log,false,0); + new G4PVPlacement(0,G4ThreeVector(0,0,TACTIC_NS::vacuum_pos),vacuum_log,"vacuum_phys",gas_volume_log,false,0); + new G4PVPlacement(0,G4ThreeVector(0,0,-TACTIC_NS::vacuum_pos),vacuum_log,"vacuum_phys",gas_volume_log,false,0); + + gas_volume_log->SetVisAttributes(m_VisGas); + window_log->SetVisAttributes(m_VisWindows); + vacuum_log->SetVisAttributes(m_VisVacuum); + m_CylindricalDetector->SetVisAttributes(m_VisChamber); + + G4UserLimits *gas_volume_step = new G4UserLimits(); + G4double maxStep = 0.1*mm; + gas_volume_step->SetMaxAllowedStep(maxStep); + gas_volume_log->SetUserLimits(gas_volume_step); + + gas_volume_log->SetSensitiveDetector(m_Scorer); + } + 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 TACTIC::ReadConfiguration(NPL::InputParser parser){ + vector<NPL::InputBlock*> blocks = parser.GetAllBlocksWithToken("TACTIC"); + if(NPOptionManager::getInstance()->GetVerboseLevel()) + cout << "//// " << blocks.size() << " detectors found " << endl; + + vector<string> cart = {"POS","Shape","GasMaterial_1","GasMaterial_2","GasFraction_1","GasFraction_2","Temperature","Pressure"}; + + for(unsigned int i = 0 ; i < blocks.size() ; i++){ + if(blocks[i]->HasTokenList(cart)){ + if(NPOptionManager::getInstance()->GetVerboseLevel()) + cout << endl << "//// TACTIC " << i+1 << endl; + + G4ThreeVector Pos = NPS::ConvertVector(blocks[i]->GetTVector3("POS","mm")); + string Shape = blocks[i]->GetString("Shape"); + m_GasMaterial.push_back(blocks[i]->GetString("GasMaterial_1")); + m_GasMaterial.push_back(blocks[i]->GetString("GasMaterial_2")); + m_GasFraction.push_back(blocks[i]->GetInt("GasFraction_1")); + m_GasFraction.push_back(blocks[i]->GetInt("GasFraction_2")); + m_Temperature = blocks[i]->GetDouble("Temperature","kelvin"); + m_Pressure = blocks[i]->GetDouble("Pressure","bar"); + AddDetector(Pos,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 TACTIC::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()*TACTIC_NS::active_length*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(),"TACTIC",world,false,i+1); + + if(!m_ReactionRegion){ + G4ProductionCuts* ecut = new G4ProductionCuts(); + ecut->SetProductionCut(1000,"e-"); //I think lowest is 900 eV for delta electron production, this is 1000 MeV to cut all electrons produced this way + m_ReactionRegion= new G4Region("NPSimulationProcess"); + m_ReactionRegion->SetProductionCuts(ecut); + m_ReactionRegion->AddRootLogicalVolume(gas_volume_log); + } + + G4FastSimulationManager* mng = m_ReactionRegion->GetFastSimulationManager(); + unsigned int size = m_ReactionModel.size(); + for(unsigned int j = 0 ; j < size ; j++){ + mng->RemoveFastSimulationModel(m_ReactionModel[j]); + } + m_ReactionModel.clear(); + + G4VFastSimulationModel* fsm; + fsm = new NPS::BeamReaction("BeamReaction",m_ReactionRegion); + m_ReactionModel.push_back(fsm); + + } +} +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +// Add Detector branch to the EventTree. +// Called After DetecorConstruction::AddDetector Method +void TACTIC::InitializeRootOutput(){ + RootOutput *pAnalysis = RootOutput::getInstance(); + TTree *pTree = pAnalysis->GetTree(); + if(!pTree->FindBranch("TACTIC")){ + pTree->Branch("TACTIC", "TTACTICData", &m_Event) ; + } + pTree->SetBranchAddress("TACTIC", &m_Event) ; +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +// Read sensitive part and fill the Root tree. +// Called at in the EventAction::EndOfEventAvtion +void TACTIC::ReadSensitive(const G4Event* event ){ + m_Event->Clear(); + + ofstream file; + + G4THitsMap<G4double*>* BeamHitMap; + std::map<G4int, G4double**>::iterator Beam_itr; + G4int BeamCollectionID = G4SDManager::GetSDMpointer()->GetCollectionID("TACTICScorer/BeamScorer"); + BeamHitMap = (G4THitsMap<G4double*>*)(event->GetHCofThisEvent()->GetHC(BeamCollectionID)); + + file.open("/Users/warren/nptool/NPSimulation/Detectors/TACTIC/out.dat",std::ios::app); + + for (Beam_itr = BeamHitMap->GetMap()->begin(); Beam_itr != BeamHitMap->GetMap()->end(); Beam_itr++) { + G4double* Info = *(Beam_itr->second); + //file << floor(((Info[3]+TACTIC_NS::active_length*0.5)/(TACTIC_NS::active_length/TACTIC_NS::NumberOfStrips))) << "\t"; // To get PAD number + file << event->GetEventID() << "\t"; + for(int s = 0; s<12; s++) { + if(s==11) file << Info[s] << endl; + else file << Info[s] << "\t"; + } + } + + BeamHitMap->clear(); + + G4THitsMap<G4double*>* EjectHitMap; + std::map<G4int, G4double**>::iterator Eject_itr; + G4int EjectCollectionID = G4SDManager::GetSDMpointer()->GetCollectionID("TACTICScorer/EjectScorer"); + EjectHitMap = (G4THitsMap<G4double*>*)(event->GetHCofThisEvent()->GetHC(EjectCollectionID)); + + for (Eject_itr = EjectHitMap->GetMap()->begin(); Eject_itr != EjectHitMap->GetMap()->end(); Eject_itr++) { + G4double* Info = *(Eject_itr->second); + //file << floor(((Info[3]+TACTIC_NS::active_length*0.5)/(TACTIC_NS::active_length/TACTIC_NS::NumberOfStrips))) << "\t"; // To get PAD number + file << event->GetEventID() << "\t"; + for(int s = 0; s<12; s++) { + if(s==11) file << Info[s] << endl; + else file << Info[s] << "\t"; + } + } + + EjectHitMap->clear(); + + file.close(); + +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//////////////////////////////////////////////////////////////// +void TACTIC::InitializeScorers() { + // This check is necessary in case the geometry is reloaded + bool already_exist = false; + m_Scorer = CheckScorer("TACTICScorer",already_exist) ; + if(already_exist) + return ; + + // Otherwise the scorer is initialised + G4VPrimitiveScorer* EjectScorer = new TACTICScorer::Gas_Scorer("EjectScorer",1,TACTIC_NS::active_length,(int)TACTIC_NS::NumberOfStrips); + G4VPrimitiveScorer* BeamScorer = new TACTICScorer::Gas_Scorer("BeamScorer",1,TACTIC_NS::active_length,(int)TACTIC_NS::NumberOfStrips); + G4SDParticleFilter* EjectFilter = new G4SDParticleFilter("EjectFilter","proton"); + G4SDParticleFilter* BeamFilter = new G4SDParticleFilter("BeamFilter"); + BeamFilter->addIon(11,21); + BeamFilter->addIon(10,18); + EjectScorer->SetFilter(EjectFilter); + BeamScorer->SetFilter(BeamFilter); + + m_Scorer->RegisterPrimitive(BeamScorer); + m_Scorer->RegisterPrimitive(EjectScorer); + + G4SDManager::GetSDMpointer()->AddNewDetector(m_Scorer); + +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//////////////////////////////////////////////////////////////////////////////// +// Construct Method to be pass to the DetectorFactory // +//////////////////////////////////////////////////////////////////////////////// +NPS::VDetector* TACTIC::Construct(){ + return (NPS::VDetector*) new TACTIC(); +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +//////////////////////////////////////////////////////////////////////////////// +// Registering the construct method to the factory // +//////////////////////////////////////////////////////////////////////////////// +extern"C" { + class proxy_nps_TACTIC{ + public: + proxy_nps_TACTIC(){ + NPS::DetectorFactory::getInstance()->AddToken("TACTIC","TACTIC"); + NPS::DetectorFactory::getInstance()->AddDetector("TACTIC",TACTIC::Construct); + } + }; + + proxy_nps_TACTIC p_nps_TACTIC; +} diff --git a/NPSimulation/Detectors/TACTIC/TACTIC.detector b/NPSimulation/Detectors/TACTIC/TACTIC.detector new file mode 100644 index 0000000000000000000000000000000000000000..36ef031cecae6c257cc5afbe45586263a489b224 --- /dev/null +++ b/NPSimulation/Detectors/TACTIC/TACTIC.detector @@ -0,0 +1,12 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +TACTIC + POS= 0 0 0 mm + Shape= Cylindrical +% GasMaterial_1 = P10_1atm + GasMaterial_1 = He_gas + GasMaterial_2 = CO2 + GasFraction_1 = 90 + GasFraction_2 = 10 + Temperature = 293.15 kelvin + Pressure = 0.5 bar +% Pressure = 1.0 bar diff --git a/NPSimulation/Detectors/TACTIC/TACTIC.hh b/NPSimulation/Detectors/TACTIC/TACTIC.hh new file mode 100644 index 0000000000000000000000000000000000000000..d48efb75596010adbb35d83b5929a9f2b21f1d80 --- /dev/null +++ b/NPSimulation/Detectors/TACTIC/TACTIC.hh @@ -0,0 +1,134 @@ +#ifndef TACTIC_h +#define TACTIC_h 1 +/***************************************************************************** + * Copyright (C) 2009-2020 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: Warren Lynch contact address: Warren.Lynch@york.ac.uk * + * * + * Creation Date : June 2020 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class describe TACTIC 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" +#include "G4UserLimits.hh" +#include "G4VFastSimulationModel.hh" +#include "G4FastSimulationManager.hh" + +// NPTool header +#include "NPSVDetector.hh" +#include "TTACTICData.h" +#include "NPInputParser.h" +#include "Decay.hh" +#include "BeamReaction.hh" + +class TACTIC : public NPS::VDetector{ + //////////////////////////////////////////////////// + /////// Default Constructor and Destructor ///////// + //////////////////////////////////////////////////// +public: + TACTIC() ; + virtual ~TACTIC() ; + + //////////////////////////////////////////////////// + /////// 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* BuildCylindricalDetector(); + +private: + G4LogicalVolume* m_CylindricalDetector; + G4LogicalVolume* gas_volume_log; + G4LogicalVolume* window_log; + G4LogicalVolume* vacuum_log; + //////////////////////////////////////////////////// + ////// 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_Scorer ; + //////////////////////////////////////////////////// + ///////////Event class to store Data//////////////// + //////////////////////////////////////////////////// +private: + TTACTICData* m_Event ; + + //////////////////////////////////////////////////// + ///////////////Private intern Data////////////////// + //////////////////////////////////////////////////// +private: // Geometry + // Detector Coordinate + vector<double> m_R; + vector<double> m_Theta; + vector<double> m_Phi; + + vector<string> m_GasMaterial; + vector<int> m_GasFraction; + + double m_Pressure; + double m_Temperature; + // Shape type + vector<string> m_Shape ; + + // Visualisation Attribute + G4VisAttributes* m_VisChamber; + G4VisAttributes* m_VisWindows; + G4VisAttributes* m_VisGas; + G4VisAttributes* m_VisVacuum; + +private: + // Region were reaction can occure: + G4Region* m_ReactionRegion; + vector<G4VFastSimulationModel*> m_ReactionModel; + + // Needed for dynamic loading of the library +public: + static NPS::VDetector* Construct(); +}; + +#endif diff --git a/NPSimulation/Detectors/TACTIC/TACTICScorer.cc b/NPSimulation/Detectors/TACTIC/TACTICScorer.cc new file mode 100644 index 0000000000000000000000000000000000000000..9265e9e3df6c24c16af3629708ad0e170cb841d5 --- /dev/null +++ b/NPSimulation/Detectors/TACTIC/TACTICScorer.cc @@ -0,0 +1,95 @@ +#include "TACTICScorer.hh" +#include "G4UnitsTable.hh" +using namespace TACTICScorer; + +Gas_Scorer::Gas_Scorer(G4String name,G4int Level,G4double ScorerLength,G4int NumberOfSegments, G4int depth) //what do level and depth do? +:G4VPrimitiveScorer(name, depth),HCID(-1){ + m_ScorerLength = ScorerLength; + m_NumberOfSegments = NumberOfSegments; + m_SegmentLength = m_ScorerLength / m_NumberOfSegments; + m_Level = Level; + + m_Position = G4ThreeVector(-1000,-1000,-1000); + m_SegmentNumber = -1; + m_Index = -1; +} + +Gas_Scorer::~Gas_Scorer(){} + +G4bool Gas_Scorer::ProcessHits(G4Step* aStep, G4TouchableHistory*){ + + G4double* Infos = new G4double[12]; + m_Position = aStep->GetPreStepPoint()->GetPosition(); + + Infos[0] = aStep->GetTrack()->GetTrackID(); + + Infos[1] = -1.; + if (aStep->GetTrack()->GetDefinition()->GetParticleName() == "Ne18") Infos[1] = 0.; + if (aStep->GetTrack()->GetDefinition()->GetParticleName() == "Na21") Infos[1] = 1.; + if (aStep->GetTrack()->GetDefinition()->GetParticleName() == "proton") Infos[1] = 2.; + if (aStep->GetTrack()->GetDefinition()->GetParticleName() == "alpha") Infos[1] = 3.; + if (aStep->GetTrack()->GetDefinition()->GetParticleName() == "Li8") Infos[1] = 4.; + if (aStep->GetTrack()->GetDefinition()->GetParticleName() == "B11") Infos[1] = 5; + if (aStep->GetTrack()->GetDefinition()->GetParticleName() == "neutron") Infos[1] = 6; + + Infos[2] = aStep->GetPreStepPoint()->GetGlobalTime(); + Infos[3] = aStep->GetPreStepPoint()->GetKineticEnergy(); + Infos[4] = aStep->GetTotalEnergyDeposit() - aStep->GetNonIonizingEnergyDeposit(); + + m_SegmentNumber = (int)((m_Position.z() + m_ScorerLength / 2.) / m_SegmentLength ) + 1; //Pad number + Infos[5] = m_SegmentNumber; + Infos[6] = m_Position.z(); + Infos[7] = pow(pow(m_Position.x(),2) + pow(m_Position.y(),2),0.5); //R + Infos[8] = aStep->GetTrack()->GetVertexPosition()[2]; + Infos[9] = aStep->GetTrack()->GetVertexKineticEnergy(); + G4ThreeVector p_vec = aStep->GetTrack()->GetVertexMomentumDirection(); + Infos[10] = acos(p_vec[2]/pow(pow(p_vec[0],2)+pow(p_vec[1],2)+pow(p_vec[2],2),0.5))/deg; //angle relative to z axis (theta); + Infos[11] = aStep->GetTrack()->GetTrackLength(); + + m_DetectorNumber = aStep->GetPreStepPoint()->GetTouchableHandle()->GetCopyNumber(m_Level); + m_Index = m_DetectorNumber * 1e3 + m_SegmentNumber * 1e6; + + map<G4int, G4double**>::iterator it; + it= EvtMap->GetMap()->find(m_Index); + if(it!=EvtMap->GetMap()->end()){ //accumulate ionisation energy deposit + G4double* dummy = *(it->second); + Infos[4]+=dummy[4]; + delete dummy; + } + + EvtMap->set(m_Index, Infos); + + return TRUE; + +} + +void Gas_Scorer::Initialize(G4HCofThisEvent* HCE){ + EvtMap = new NPS::HitsMap<G4double*>(GetMultiFunctionalDetector()->GetName(), GetName()); + if (HCID < 0) { + HCID = GetCollectionID(0); + } + HCE->AddHitsCollection(HCID, (G4VHitsCollection*)EvtMap); +} + +void Gas_Scorer::EndOfEvent(G4HCofThisEvent*){} + +void Gas_Scorer::clear(){ + std::map<G4int, G4double**>::iterator MapIterator; + for (MapIterator = EvtMap->GetMap()->begin() ; MapIterator != EvtMap->GetMap()->end() ; MapIterator++){ + delete *(MapIterator->second); + } + + EvtMap->clear(); +} + + +void Gas_Scorer::DrawAll(){} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... + +void Gas_Scorer::PrintAll(){ + G4cout << " MultiFunctionalDet " << detector->GetName() << G4endl ; + G4cout << " PrimitiveScorer " << GetName() << G4endl ; + G4cout << " Number of entries " << EvtMap->entries() << G4endl ; +} + diff --git a/NPSimulation/Detectors/TACTIC/TACTICScorer.hh b/NPSimulation/Detectors/TACTIC/TACTICScorer.hh new file mode 100644 index 0000000000000000000000000000000000000000..dfe7a0305ed7e4d0dfb3d64d3fcdc738bb6c76f3 --- /dev/null +++ b/NPSimulation/Detectors/TACTIC/TACTICScorer.hh @@ -0,0 +1,55 @@ +#ifndef TACTICScorer_h +#define TACTICScorer_h 1 + +#include "G4VPrimitiveScorer.hh" +#include "NPSHitsMap.hh" +#include <map> + +using namespace std; +using namespace CLHEP; + +namespace TACTICScorer { + + class Gas_Scorer : public G4VPrimitiveScorer{ + + public: + Gas_Scorer(G4String name, + G4int Level, + G4double ScorerLength, + G4int NumberOfSegments, + G4int depth=0); + ~Gas_Scorer(); + + protected: // with description + G4bool ProcessHits(G4Step*, G4TouchableHistory*); + + public: + void Initialize(G4HCofThisEvent*); + void EndOfEvent(G4HCofThisEvent*); + void clear(); + void DrawAll(); + void PrintAll(); + + private: // Geometry of the detector + G4double m_ScorerLength; + G4int m_NumberOfSegments; + G4double m_SegmentLength; + // Level at which to find the copy number linked to the detector number + G4int m_Level; + + private: // inherited from G4VPrimitiveScorer + G4int HCID; + NPS::HitsMap<G4double*>* EvtMap; + + + private: // Needed for intermediate calculation (avoid multiple instantiation in Processing Hit) + G4ThreeVector m_Position ; + G4int m_DetectorNumber ; + G4int m_SegmentNumber ; + G4long m_Index ; + + }; + +} + +#endif diff --git a/NPSimulation/Detectors/TACTIC/run.mac b/NPSimulation/Detectors/TACTIC/run.mac new file mode 100644 index 0000000000000000000000000000000000000000..9cf95ba556fcbf624dcfe4319eaf892c49289489 --- /dev/null +++ b/NPSimulation/Detectors/TACTIC/run.mac @@ -0,0 +1,2 @@ +/run/beamOn 100 +/exit \ No newline at end of file diff --git a/NPSimulation/Process/BeamReaction.cc b/NPSimulation/Process/BeamReaction.cc index f2412ef44c66a9ddb3bd933849648b98b85ce1a3..32a54e0eb2bae27b18cecc415ac0e6ffe8b79e6a 100644 --- a/NPSimulation/Process/BeamReaction.cc +++ b/NPSimulation/Process/BeamReaction.cc @@ -25,6 +25,7 @@ #include "G4Electron.hh" #include "G4Gamma.hh" #include "G4SystemOfUnits.hh" +#include "G4EmCalculator.hh" #include "G4VPhysicalVolume.hh" #include "NPFunction.h" #include "NPInputParser.h" @@ -34,71 +35,66 @@ #include <string> //////////////////////////////////////////////////////////////////////////////// NPS::BeamReaction::BeamReaction(G4String modelName, G4Region* envelope) - : G4VFastSimulationModel(modelName, envelope) { - ReadConfiguration(); - m_PreviousEnergy = 0; - m_PreviousLength = 0; -} + : G4VFastSimulationModel(modelName, envelope) { + ReadConfiguration(); + m_shoot=false; + m_rand=0; + m_Z=0; + } //////////////////////////////////////////////////////////////////////////////// NPS::BeamReaction::BeamReaction(G4String modelName) - : G4VFastSimulationModel(modelName) {} + : G4VFastSimulationModel(modelName) {} -//////////////////////////////////////////////////////////////////////////////// -NPS::BeamReaction::~BeamReaction() {} + //////////////////////////////////////////////////////////////////////////////// + NPS::BeamReaction::~BeamReaction() {} -//////////////////////////////////////////////////////////////////////////////// -void NPS::BeamReaction::AttachReactionConditions() { - // Reasssigned the branch address - if (RootOutput::getInstance()->GetTree()->FindBranch("ReactionConditions")) - RootOutput::getInstance()->GetTree()->SetBranchAddress( - "ReactionConditions", &m_ReactionConditions); -} + //////////////////////////////////////////////////////////////////////////////// + void NPS::BeamReaction::AttachReactionConditions() { + // Reasssigned the branch address + if (RootOutput::getInstance()->GetTree()->FindBranch("ReactionConditions")) + RootOutput::getInstance()->GetTree()->SetBranchAddress( + "ReactionConditions", &m_ReactionConditions); + } //////////////////////////////////////////////////////////////////////////////// void NPS::BeamReaction::ReadConfiguration() { NPL::InputParser input(NPOptionManager::getInstance()->GetReactionFile()); - //vector<NPL::InputBlock*> blocks; - //blocks = input.GetAllBlocksWithToken("TwoBodyReaction"); - //if(blocks.size()>0) m_ReactionType ="TwoBodyReaction"; - // - //blocks = input.GetAllBlocksWithToken("QFSReaction"); - //if(blocks.size()>0) m_ReactionType ="QFSReaction"; - if(input.GetAllBlocksWithToken("TwoBodyReaction").size()>0) m_ReactionType ="TwoBodyReaction"; - if(input.GetAllBlocksWithToken("QFSReaction").size()>0) m_ReactionType ="QFSReaction"; + else if(input.GetAllBlocksWithToken("QFSReaction").size()>0) m_ReactionType ="QFSReaction"; if (m_ReactionType=="TwoBodyReaction" ) { - m_Reaction.ReadConfigurationFile(input); - m_BeamName = NPL::ChangeNameToG4Standard(m_Reaction.GetNucleus1()->GetName()); - if(m_Reaction.GetNucleus3()->GetName() != ""){ - m_active = true; - m_ReactionConditions = new TReactionConditions(); - AttachReactionConditions(); - if (!RootOutput::getInstance()->GetTree()->FindBranch("ReactionConditions")) - RootOutput::getInstance()->GetTree()->Branch( - "ReactionConditions", "TReactionConditions", &m_ReactionConditions); - } - } else if (m_ReactionType=="QFSReaction") { - m_QFS.ReadConfigurationFile(input); - m_BeamName = NPL::ChangeNameToG4Standard(m_QFS.GetNucleusA()->GetName()); + m_Reaction.ReadConfigurationFile(input); + m_BeamName = NPL::ChangeNameToG4Standard(m_Reaction.GetNucleus1()->GetName()); + if(m_Reaction.GetNucleus3()->GetName() != ""){ m_active = true; m_ReactionConditions = new TReactionConditions(); AttachReactionConditions(); if (!RootOutput::getInstance()->GetTree()->FindBranch("ReactionConditions")) - RootOutput::getInstance()->GetTree()->Branch( - "ReactionConditions", "TReactionConditions", &m_ReactionConditions); + RootOutput::getInstance()->GetTree()->Branch( + "ReactionConditions", "TReactionConditions", &m_ReactionConditions); + } + } + + else if (m_ReactionType=="QFSReaction") { + m_QFS.ReadConfigurationFile(input); + m_BeamName = NPL::ChangeNameToG4Standard(m_QFS.GetNucleusA()->GetName()); + m_active = true; + m_ReactionConditions = new TReactionConditions(); + AttachReactionConditions(); + if (!RootOutput::getInstance()->GetTree()->FindBranch("ReactionConditions")) + RootOutput::getInstance()->GetTree()->Branch( + "ReactionConditions", "TReactionConditions", &m_ReactionConditions); } else { - m_active = false; + m_active = false; } } //////////////////////////////////////////////////////////////////////////////// -G4bool -NPS::BeamReaction::IsApplicable(const G4ParticleDefinition& particleType) { +G4bool NPS::BeamReaction::IsApplicable(const G4ParticleDefinition& particleType) { if (!m_active) return false; @@ -113,481 +109,493 @@ NPS::BeamReaction::IsApplicable(const G4ParticleDefinition& particleType) { //////////////////////////////////////////////////////////////////////////////// G4bool NPS::BeamReaction::ModelTrigger(const G4FastTrack& fastTrack) { - - //cout<< "MODEL TRIG"<<endl; - static bool shoot = false; - static double rand = 0; + //cout<< "--------- MODEL TRIG ---------"<<endl; const G4Track* PrimaryTrack = fastTrack.GetPrimaryTrack(); - G4ThreeVector V = PrimaryTrack->GetMomentum().unit(); - G4ThreeVector P = fastTrack.GetPrimaryTrackLocalPosition(); - G4VSolid* solid = fastTrack.GetPrimaryTrack() - ->GetVolume() - ->GetLogicalVolume() - ->GetSolid(); - double in = solid->DistanceToOut(P, V); - double out = solid->DistanceToOut(P, -V); - double ratio = in / (out + in); - m_Parent_ID = PrimaryTrack->GetParentID(); // process reserved to the beam if(m_Parent_ID!=0) return false; - //cout<< "in:"<<in<<std::scientific<<endl; - //cout<< "ou:"<<out<<std::scientific<<endl; - //cout<< "ratio:"<<ratio<<std::scientific<<endl; - // m_StepSize = m_StepSize/100000.; + G4ThreeVector V = PrimaryTrack->GetMomentum().unit(); + G4ThreeVector P = fastTrack.GetPrimaryTrackLocalPosition(); + G4VSolid* solid = fastTrack.GetPrimaryTrack() + ->GetVolume() + ->GetLogicalVolume() + ->GetSolid(); + double to_exit = solid->DistanceToOut(P, V); + double to_entrance = solid->DistanceToOut(P, -V); + bool is_first = (to_entrance==0); + + if(is_first && m_shoot){ + std::cout << "Something went wrong in beam reaction, m_shoot cannot be true at beginning of event" << std::endl; + std::cout << "rand: " << m_rand << std::endl; + m_shoot = false; + } - if (out == 0) { // first step of current event - //cout<< "FIRST"<<endl; - rand = G4RandFlat::shoot(); - m_PreviousLength = m_StepSize; - m_PreviousEnergy = PrimaryTrack->GetKineticEnergy(); + if(is_first){ + m_rand = G4RandFlat::shoot(); + // random Z in the Volume + m_Z = m_rand*(to_exit+to_entrance)-0.5*(to_exit+to_entrance); // Clear Previous Event m_ReactionConditions->Clear(); - shoot = true; - } - else if (((in-m_StepSize) <= 1E-9) && shoot) { // last step - //cout<< "LAST"<<endl; - return true; + m_shoot=true; } - - //cout.precision(17); - //cout<< "rand:"<<rand<<std::scientific<<endl; - + + // curviligne coordinate along beam patch + double S = to_entrance - 0.5*(to_exit+to_entrance); + m_length = m_Z-S; // If the condition is met, the event is generated - if (ratio < rand) { - - // Reset the static for next event - // shoot = false; + if (m_shoot && m_length < m_StepSize) { if(m_ReactionType=="QFSReaction"){ - if ( shoot && m_QFS.IsAllowed() ) { - shoot = false; - return true; - } else { - return false; - } + if ( m_QFS.IsAllowed() ) { + return true; + } + else{ + m_shoot=false; + std::cout << "QFS not allowed" << std::endl; + } } - + else if(m_ReactionType=="TwoBodyReaction"){ - if ( shoot && m_Reaction.IsAllowed(PrimaryTrack->GetKineticEnergy()) ) { - shoot = false; - return true; - } else { - return false; - } - }else{ - return false; + if ( m_Reaction.IsAllowed(PrimaryTrack->GetKineticEnergy()) ) { + return true; + } + else{ + m_shoot=false; + std::cout << "Two body reaction not allowed" << std::endl; + } } } - // Record the situation of the current step - // so it can be used in the next one - if (!PrimaryTrack->GetStep()->IsLastStepInVolume()) { - m_PreviousLength = PrimaryTrack->GetStep()->GetStepLength(); - //cout<< "PreviousLength="<<m_PreviousLength<<endl; - m_PreviousEnergy = PrimaryTrack->GetKineticEnergy(); - } - return false; } //////////////////////////////////////////////////////////////////////////////// void NPS::BeamReaction::DoIt(const G4FastTrack& fastTrack, - G4FastStep& fastStep) { - - // Get the track info - const G4Track* PrimaryTrack = fastTrack.GetPrimaryTrack(); - G4ThreeVector pdirection = PrimaryTrack->GetMomentum().unit(); - G4ThreeVector localdir = fastTrack.GetPrimaryTrackLocalDirection(); - - G4ThreeVector worldPosition = PrimaryTrack->GetPosition(); - G4ThreeVector localPosition = fastTrack.GetPrimaryTrackLocalPosition(); - - double energy = PrimaryTrack->GetKineticEnergy(); - double time = PrimaryTrack->GetGlobalTime(); - - // Randomize within the step - // Assume energy loss is linear within the step - // Assume no scattering - double rand = G4RandFlat::shoot(); - double length = rand * (m_PreviousLength); - energy -= (1 - rand) * (m_PreviousEnergy - energy); - G4ThreeVector ldir = pdirection; - ldir *= length; - localPosition = localPosition - ldir; - // Set the end of the step conditions - fastStep.SetPrimaryTrackFinalKineticEnergyAndDirection(0, pdirection); - fastStep.SetPrimaryTrackFinalPosition(worldPosition); - fastStep.SetTotalEnergyDeposited(0); - fastStep.SetPrimaryTrackFinalTime(time); - fastStep.KillPrimaryTrack(); - fastStep.SetPrimaryTrackPathLength(0.0); - - - if (m_ReactionType=="TwoBodyReaction" ) { - - /////////////////////////////// - // Two-Body Reaction Case ///// - /////////////////////////////// - - //////Define the kind of particle to shoot//////// - // Nucleus 3 - int LightZ = m_Reaction.GetNucleus3()->GetZ(); - int LightA = m_Reaction.GetNucleus3()->GetA(); - static G4IonTable* IonTable - = G4ParticleTable::GetParticleTable()->GetIonTable(); - - G4ParticleDefinition* LightName; - - if (LightZ == 0 && LightA == 1) // neutron is special case - { - LightName = G4Neutron::Definition(); - } else { - if (m_Reaction.GetUseExInGeant4()) - LightName - = IonTable->GetIon(LightZ, LightA, m_Reaction.GetExcitation3() * MeV); - else - LightName = IonTable->GetIon(LightZ, LightA); - } - - // Nucleus 4 - G4int HeavyZ = m_Reaction.GetNucleus4()->GetZ(); - G4int HeavyA = m_Reaction.GetNucleus4()->GetA(); - - // Generate the excitation energy if a distribution is given - m_Reaction.ShootRandomExcitationEnergy(); - - // Use to clean up the IonTable in case of the Ex changing at every event - G4ParticleDefinition* HeavyName; - - if (m_Reaction.GetUseExInGeant4()) - HeavyName - = IonTable->GetIon(HeavyZ, HeavyA, m_Reaction.GetExcitation4() * MeV); - else - HeavyName = IonTable->GetIon(HeavyZ, HeavyA); - - // Set the Energy of the reaction - m_Reaction.SetBeamEnergy(energy); - - double Beam_theta = pdirection.theta(); - double Beam_phi = pdirection.phi(); - - /////////////////////////// - ///// Beam Parameters ///// - /////////////////////////// - m_ReactionConditions->SetBeamParticleName( - PrimaryTrack->GetParticleDefinition()->GetParticleName()); - - m_ReactionConditions->SetBeamReactionEnergy(energy); - m_ReactionConditions->SetVertexPositionX(localPosition.x()); - m_ReactionConditions->SetVertexPositionY(localPosition.y()); - m_ReactionConditions->SetVertexPositionZ(localPosition.z()); - - G4ThreeVector U(1, 0, 0); - G4ThreeVector V(0, 1, 0); - G4ThreeVector ZZ(0, 0, 1); - m_ReactionConditions->SetBeamEmittanceTheta( - PrimaryTrack->GetMomentumDirection().theta() / deg); - m_ReactionConditions->SetBeamEmittancePhi( - PrimaryTrack->GetMomentumDirection().phi() / deg); - m_ReactionConditions->SetBeamEmittanceThetaX( - PrimaryTrack->GetMomentumDirection().angle(U) / deg); - m_ReactionConditions->SetBeamEmittancePhiY( - PrimaryTrack->GetMomentumDirection().angle(V) / deg); - - ////////////////////////////////////////////////////////// - ///// Build rotation matrix to go from the incident ////// - ///// beam frame to the "world" frame ////// - ////////////////////////////////////////////////////////// - - - // G4ThreeVector col1(cos(Beam_theta) * cos(Beam_phi), - // cos(Beam_theta) * sin(Beam_phi), - // -sin(Beam_theta)); - // G4ThreeVector col2(-sin(Beam_phi), - // cos(Beam_phi), - // 0); - // G4ThreeVector col3(sin(Beam_theta) * cos(Beam_phi), - // sin(Beam_theta) * sin(Beam_phi), - // cos(Beam_theta)); - // G4RotationMatrix BeamToWorld(col1, col2, col3); - - ///////////////////////////////////////////////////////////////// - ///// Angles for emitted particles following Cross Section ////// - ///// Angles are in the beam frame ////// - ///////////////////////////////////////////////////////////////// - - // Angles - // Shoot and Set a Random ThetaCM - m_Reaction.ShootRandomThetaCM(); - double phi = G4RandFlat::shoot() * 2. * pi; - - ////////////////////////////////////////////////// - ///// Momentum and angles from kinematics ///// - ///// Angles are in the beam frame ///// - ////////////////////////////////////////////////// - // Variable where to store results - double Theta3, Energy3, Theta4, Energy4; - - // Compute Kinematic using previously defined ThetaCM - m_Reaction.KineRelativistic(Theta3, Energy3, Theta4, Energy4); - // Momentum in beam frame for light particle - G4ThreeVector momentum_kine3_beam(sin(Theta3) * cos(phi), - sin(Theta3) * sin(phi), cos(Theta3)); - // Momentum in World frame //to go from the incident beam frame to the "world" - // frame - G4ThreeVector momentum_kine3_world = momentum_kine3_beam; - momentum_kine3_world.rotate(Beam_theta, - V); // rotation of Beam_theta on Y axis - momentum_kine3_world.rotate(Beam_phi, ZZ); // rotation of Beam_phi on Z axis - - // Momentum in beam frame for heavy particle - G4ThreeVector momentum_kine4_beam(sin(Theta4) * cos(phi + pi), - sin(Theta4) * sin(phi + pi), cos(Theta4)); - // Momentum in World frame - G4ThreeVector momentum_kine4_world = momentum_kine4_beam; - momentum_kine4_world.rotate(Beam_theta, - V); // rotation of Beam_theta on Y axis - momentum_kine4_world.rotate(Beam_phi, ZZ); // rotation of Beam_phi on Z axis - - // Emitt secondary - if (m_Reaction.GetShoot3()) { - G4DynamicParticle particle3(LightName, momentum_kine3_world, Energy3); - fastStep.CreateSecondaryTrack(particle3, localPosition, time); - } - - if (m_Reaction.GetShoot4()) { - G4DynamicParticle particle4(HeavyName, momentum_kine4_world, Energy4); - fastStep.CreateSecondaryTrack(particle4, localPosition, time); - } - - // Reinit for next event - m_PreviousEnergy = 0; - m_PreviousLength = 0; - - /////////////////////////////////////// - ///// Emitted particle Parameters ///// - /////////////////////////////////////// - // Names 3 and 4// - m_ReactionConditions->SetParticleName(LightName->GetParticleName()); - m_ReactionConditions->SetParticleName(HeavyName->GetParticleName()); - // Angle 3 and 4 // - m_ReactionConditions->SetTheta(Theta3 / deg); - m_ReactionConditions->SetTheta(Theta4 / deg); - - m_ReactionConditions->SetPhi(phi / deg); - if ((phi + pi) / deg > 360) - m_ReactionConditions->SetPhi((phi - pi) / deg); - else - m_ReactionConditions->SetPhi((phi + pi) / deg); - - // Energy 3 and 4 // - m_ReactionConditions->SetKineticEnergy(Energy3); - m_ReactionConditions->SetKineticEnergy(Energy4); - // ThetaCM and Ex// - m_ReactionConditions->SetThetaCM(m_Reaction.GetThetaCM() / deg); - m_ReactionConditions->SetExcitationEnergy3(m_Reaction.GetExcitation3()); - m_ReactionConditions->SetExcitationEnergy4(m_Reaction.GetExcitation4()); - // Momuntum X 3 and 4 // - m_ReactionConditions->SetMomentumDirectionX(momentum_kine3_world.x()); - m_ReactionConditions->SetMomentumDirectionX(momentum_kine4_world.x()); - // Momuntum Y 3 and 4 // - m_ReactionConditions->SetMomentumDirectionY(momentum_kine3_world.y()); - m_ReactionConditions->SetMomentumDirectionY(momentum_kine4_world.y()); - // Momuntum Z 3 and 4 // - m_ReactionConditions->SetMomentumDirectionZ(momentum_kine3_world.z()); - m_ReactionConditions->SetMomentumDirectionZ(momentum_kine4_world.z()); - - }// end if TwoBodyReaction - - else if (m_ReactionType=="QFSReaction" ) { - - //////Define the kind of particle to shoot//////// - // A --> T ==> B + (c -> T) => B + 1 + 2 - - int Light1_Z = m_QFS.GetNucleus1()->GetZ(); - int Light1_A = m_QFS.GetNucleus1()->GetA(); - int Light2_Z = m_QFS.GetNucleus2()->GetZ(); - int Light2_A = m_QFS.GetNucleus2()->GetA(); - - static G4IonTable* IonTable - = G4ParticleTable::GetParticleTable()->GetIonTable(); - - G4ParticleDefinition* Light1Name; - G4ParticleDefinition* Light2Name; - - if (Light1_Z == 0 && Light1_A == 1) // neutron is special case - { - Light1Name = G4Neutron::Definition(); - } else { - Light1Name = IonTable->GetIon(Light1_Z, Light1_A); - } - - if (Light2_Z == 0 && Light2_A == 1) // neutron is special case - { - Light2Name = G4Neutron::Definition(); - } else { - Light2Name = IonTable->GetIon(Light2_Z, Light2_A); - } - - // Nucleus B - G4int Heavy_Z = m_QFS.GetNucleusB()->GetZ(); - G4int Heavy_A = m_QFS.GetNucleusB()->GetA(); - - G4ParticleDefinition* HeavyName; - HeavyName = IonTable->GetIon(Heavy_Z, Heavy_A); - - // Set the Energy of the reaction - m_QFS.SetBeamEnergy(energy); - - double Beam_theta = pdirection.theta(); - double Beam_phi = pdirection.phi(); - - - ///////////////////////////////////////////////////////////////// - ///// Angles for emitted particles following Cross Section ////// - ///// Angles are in the beam frame ////// - ///////////////////////////////////////////////////////////////// - - // Angles - // Shoot and Set a Random ThetaCM - //m_QFS.ShootRandomThetaCM(); - //m_QFS.ShootRandomPhiCM(); - double theta = G4RandFlat::shoot() * pi; - double phi = G4RandFlat::shoot() * 2. * pi - pi; //rand in [-pi,pi] - double momX = gRandom->Gaus(0.,m_QFS.GetMomentumSigma()); - double momY = gRandom->Gaus(0.,m_QFS.GetMomentumSigma()); - double momZ = gRandom->Gaus(0.,m_QFS.GetMomentumSigma()); - TVector3 mom(momX, momY, momZ); - - m_QFS.SetThetaCM(theta); - m_QFS.SetPhiCM(phi); - m_QFS.SetInternalMomentum(mom); - - ////////////////////////////////////////////////// - ///// Momentum and angles from kinematics ///// - ////////////////////////////////////////////////// - // Variable where to store results - double Theta1, Phi1, TKE1, Theta2, Phi2, TKE2, ThetaB, PhiB, TKEB; - - // Compute Kinematic using previously defined ThetaCM - m_QFS.KineRelativistic(Theta1, Phi1, TKE1, Theta2, Phi2, TKE2); - - G4ThreeVector U(1, 0, 0); - G4ThreeVector V(0, 1, 0); - G4ThreeVector ZZ(0, 0, 1); - - // Momentum in beam and world frame for light particle 1 - G4ThreeVector momentum_kine1_beam(sin(Theta1) * cos(Phi1), - sin(Theta1) * sin(Phi1), cos(Theta1)); - G4ThreeVector momentum_kine1_world = momentum_kine1_beam; - momentum_kine1_world.rotate(Beam_theta, V); // rotation of Beam_theta on Y axis - momentum_kine1_world.rotate(Beam_phi, ZZ); // rotation of Beam_phi on Z axis - - // Momentum in beam and world frame for light particle 2 - G4ThreeVector momentum_kine2_beam(sin(Theta2) * cos(Phi2), - sin(Theta2) * sin(Phi2), cos(Theta2)); - G4ThreeVector momentum_kine2_world = momentum_kine2_beam; - momentum_kine2_world.rotate(Beam_theta, V); // rotation of Beam_theta on Y axis - momentum_kine2_world.rotate(Beam_phi, ZZ); // rotation of Beam_phi on Z axis - - // Momentum in beam and world frame for heavy residual - // - //G4ThreeVector momentum_kineB_beam(sin(ThetaB) * cos(PhiB + pi), - // sin(ThetaB) * sin(PhiB + pi), cos(ThetaB)); - //G4ThreeVector momentum_kineB_world = momentum_kineB_beam; - //momentum_kineB_world.rotate(Beam_theta, V); // rotation of Beam_theta on Y axis - //momentum_kineB_world.rotate(Beam_phi, ZZ); // rotation of Beam_phi on Z axis - - TLorentzVector* P_A = m_QFS.GetEnergyImpulsionLab_A(); - TLorentzVector* P_B = m_QFS.GetEnergyImpulsionLab_B(); - - G4ThreeVector momentum_kineB_beam( P_B->Px(), P_B->Py(), P_B->Pz() ); - momentum_kineB_beam = momentum_kineB_beam.unit(); - TKEB = m_QFS.GetEnergyImpulsionLab_B()->Energy() - m_QFS.GetNucleusB()->Mass(); - G4ThreeVector momentum_kineB_world = momentum_kineB_beam; - momentum_kineB_world.rotate(Beam_theta, V); // rotation of Beam_theta on Y axis - momentum_kineB_world.rotate(Beam_phi, ZZ); // rotation of Beam_phi on Z axis - - ThetaB = P_B->Angle(P_A->Vect()); - if (ThetaB < 0) ThetaB += M_PI; - PhiB = M_PI + P_B->Vect().Phi(); - if (fabs(PhiB) < 1e-6) PhiB = 0; + G4FastStep& fastStep) { + + // std::cout << "DOIT" << std::endl; + m_shoot=false; + + // Get the track info + const G4Track* PrimaryTrack = fastTrack.GetPrimaryTrack(); + G4ThreeVector pdirection = PrimaryTrack->GetMomentum().unit(); + G4ThreeVector localdir = fastTrack.GetPrimaryTrackLocalDirection(); + + G4ThreeVector worldPosition = PrimaryTrack->GetPosition(); + G4ThreeVector localPosition = fastTrack.GetPrimaryTrackLocalPosition(); + G4Material* material = fastTrack.GetPrimaryTrack() + ->GetVolume() + ->GetLogicalVolume() + ->GetMaterial(); + double energy = PrimaryTrack->GetKineticEnergy(); + double speed = PrimaryTrack->GetVelocity(); + double time = PrimaryTrack->GetGlobalTime()+m_length/speed; + + + double reac_energy = SlowDownBeam ( + PrimaryTrack->GetParticleDefinition(), + energy, + m_length, + material); - // Emitt secondary - if (m_QFS.GetShoot1()) { - G4DynamicParticle particle1(Light1Name, momentum_kine1_world, TKE1); - fastStep.CreateSecondaryTrack(particle1, localPosition, time); - } - - if (m_QFS.GetShoot2()) { - G4DynamicParticle particle2(Light2Name, momentum_kine2_world, TKE2); - fastStep.CreateSecondaryTrack(particle2, localPosition, time); - } - if (m_QFS.GetShootB()) { - G4DynamicParticle particleB(HeavyName, momentum_kineB_world, TKEB); - fastStep.CreateSecondaryTrack(particleB, localPosition, time); - } - - // Reinit for next event - m_PreviousEnergy = 0; - m_PreviousLength = 0; - - - /////////////////////////////////// - ///// Reaction Condition Save ///// - /////////////////////////////////// - m_ReactionConditions->SetBeamParticleName( - PrimaryTrack->GetParticleDefinition()->GetParticleName()); - m_ReactionConditions->SetBeamReactionEnergy(energy); - m_ReactionConditions->SetVertexPositionX(localPosition.x()); - m_ReactionConditions->SetVertexPositionY(localPosition.y()); - m_ReactionConditions->SetVertexPositionZ(localPosition.z()); - m_ReactionConditions->SetBeamEmittanceTheta( - PrimaryTrack->GetMomentumDirection().theta() / deg); - m_ReactionConditions->SetBeamEmittancePhi( - PrimaryTrack->GetMomentumDirection().phi() / deg); - m_ReactionConditions->SetBeamEmittanceThetaX( - PrimaryTrack->GetMomentumDirection().angle(U) / deg); - m_ReactionConditions->SetBeamEmittancePhiY( - PrimaryTrack->GetMomentumDirection().angle(V) / deg); - - // Names 1,2 and B// - m_ReactionConditions->SetParticleName(Light1Name->GetParticleName()); - m_ReactionConditions->SetParticleName(Light2Name->GetParticleName()); - m_ReactionConditions->SetParticleName(HeavyName->GetParticleName()); - // Angle 1,2 and B // - m_ReactionConditions->SetTheta(Theta1 / deg); - m_ReactionConditions->SetTheta(Theta2 / deg); - m_ReactionConditions->SetTheta(ThetaB / deg); - m_ReactionConditions->SetPhi(Phi1 / deg); - m_ReactionConditions->SetPhi(Phi2 / deg); - m_ReactionConditions->SetPhi(PhiB / deg); - // Energy 1,2 and B // - m_ReactionConditions->SetKineticEnergy(TKE1); - m_ReactionConditions->SetKineticEnergy(TKE2); - m_ReactionConditions->SetKineticEnergy(TKEB); - // ThetaCM, Ex and Internal Momentum of removed cluster// - m_ReactionConditions->SetThetaCM(m_QFS.GetThetaCM() / deg); - m_ReactionConditions->SetInternalMomentum(m_QFS.GetInternalMomentum()); - //m_ReactionConditions->SetExcitationEnergy3(m_QFS.GetExcitation3()); - //m_ReactionConditions->SetExcitationEnergy4(m_QFS.GetExcitation4()); - // Momuntum X 3 and 4 // - m_ReactionConditions->SetMomentumDirectionX(momentum_kine1_world.x()); - m_ReactionConditions->SetMomentumDirectionX(momentum_kine2_world.x()); - m_ReactionConditions->SetMomentumDirectionX(momentum_kineB_world.x()); - // Momuntum Y 3 and 4 // - m_ReactionConditions->SetMomentumDirectionY(momentum_kine1_world.y()); - m_ReactionConditions->SetMomentumDirectionY(momentum_kine2_world.y()); - m_ReactionConditions->SetMomentumDirectionY(momentum_kineB_world.y()); - // Momuntum Z 3 and 4 // - m_ReactionConditions->SetMomentumDirectionZ(momentum_kine1_world.z()); - m_ReactionConditions->SetMomentumDirectionZ(momentum_kine2_world.z()); - m_ReactionConditions->SetMomentumDirectionZ(momentum_kineB_world.z()); + G4ThreeVector ldir = pdirection; + ldir *= m_length; + localPosition = localPosition + ldir; + + // Set the end of the step conditions + fastStep.SetPrimaryTrackFinalKineticEnergyAndDirection(0, pdirection); + fastStep.SetPrimaryTrackFinalPosition(worldPosition); + fastStep.SetTotalEnergyDeposited(0); + fastStep.SetPrimaryTrackFinalTime(time);// FIXME + fastStep.KillPrimaryTrack(); + fastStep.SetPrimaryTrackPathLength(0.0); + + + if (m_ReactionType=="TwoBodyReaction" ) { + + /////////////////////////////// + // Two-Body Reaction Case ///// + /////////////////////////////// + + //////Define the kind of particle to shoot//////// + // Nucleus 3 + int LightZ = m_Reaction.GetNucleus3()->GetZ(); + int LightA = m_Reaction.GetNucleus3()->GetA(); + static G4IonTable* IonTable + = G4ParticleTable::GetParticleTable()->GetIonTable(); + + G4ParticleDefinition* LightName; + + if (LightZ == 0 && LightA == 1) // neutron is special case + { + LightName = G4Neutron::Definition(); + } else { + if (m_Reaction.GetUseExInGeant4()) + LightName + = IonTable->GetIon(LightZ, LightA, m_Reaction.GetExcitation3() * MeV); + else + LightName = IonTable->GetIon(LightZ, LightA); + } + + // Nucleus 4 + G4int HeavyZ = m_Reaction.GetNucleus4()->GetZ(); + G4int HeavyA = m_Reaction.GetNucleus4()->GetA(); + + // Generate the excitation energy if a distribution is given + m_Reaction.ShootRandomExcitationEnergy(); + + // Use to clean up the IonTable in case of the Ex changing at every event + G4ParticleDefinition* HeavyName; + + if (m_Reaction.GetUseExInGeant4()) + HeavyName + = IonTable->GetIon(HeavyZ, HeavyA, m_Reaction.GetExcitation4() * MeV); + else + HeavyName = IonTable->GetIon(HeavyZ, HeavyA); + + // Set the Energy of the reaction + m_Reaction.SetBeamEnergy(reac_energy); + + double Beam_theta = pdirection.theta(); + double Beam_phi = pdirection.phi(); + + /////////////////////////// + ///// Beam Parameters ///// + /////////////////////////// + m_ReactionConditions->SetBeamParticleName( + PrimaryTrack->GetParticleDefinition()->GetParticleName()); + + m_ReactionConditions->SetBeamReactionEnergy(reac_energy); + m_ReactionConditions->SetVertexPositionX(localPosition.x()); + m_ReactionConditions->SetVertexPositionY(localPosition.y()); + m_ReactionConditions->SetVertexPositionZ(localPosition.z()); + + G4ThreeVector U(1, 0, 0); + G4ThreeVector V(0, 1, 0); + G4ThreeVector ZZ(0, 0, 1); + m_ReactionConditions->SetBeamEmittanceTheta( + PrimaryTrack->GetMomentumDirection().theta() / deg); + m_ReactionConditions->SetBeamEmittancePhi( + PrimaryTrack->GetMomentumDirection().phi() / deg); + m_ReactionConditions->SetBeamEmittanceThetaX( + PrimaryTrack->GetMomentumDirection().angle(U) / deg); + m_ReactionConditions->SetBeamEmittancePhiY( + PrimaryTrack->GetMomentumDirection().angle(V) / deg); + + ////////////////////////////////////////////////////////// + ///// Build rotation matrix to go from the incident ////// + ///// beam frame to the "world" frame ////// + ////////////////////////////////////////////////////////// + + + // G4ThreeVector col1(cos(Beam_theta) * cos(Beam_phi), + // cos(Beam_theta) * sin(Beam_phi), + // -sin(Beam_theta)); + // G4ThreeVector col2(-sin(Beam_phi), + // cos(Beam_phi), + // 0); + // G4ThreeVector col3(sin(Beam_theta) * cos(Beam_phi), + // sin(Beam_theta) * sin(Beam_phi), + // cos(Beam_theta)); + // G4RotationMatrix BeamToWorld(col1, col2, col3); + + ///////////////////////////////////////////////////////////////// + ///// Angles for emitted particles following Cross Section ////// + ///// Angles are in the beam frame ////// + ///////////////////////////////////////////////////////////////// + + // Angles + // Shoot and Set a Random ThetaCM + m_Reaction.ShootRandomThetaCM(); + double phi = G4RandFlat::shoot() * 2. * pi; + + ////////////////////////////////////////////////// + ///// Momentum and angles from kinematics ///// + ///// Angles are in the beam frame ///// + ////////////////////////////////////////////////// + // Variable where to store results + double Theta3, Energy3, Theta4, Energy4; + + // Compute Kinematic using previously defined ThetaCM + m_Reaction.KineRelativistic(Theta3, Energy3, Theta4, Energy4); + // Momentum in beam frame for light particle + G4ThreeVector momentum_kine3_beam(sin(Theta3) * cos(phi), + sin(Theta3) * sin(phi), cos(Theta3)); + // Momentum in World frame //to go from the incident beam frame to the "world" + // frame + G4ThreeVector momentum_kine3_world = momentum_kine3_beam; + momentum_kine3_world.rotate(Beam_theta, + V); // rotation of Beam_theta on Y axis + momentum_kine3_world.rotate(Beam_phi, ZZ); // rotation of Beam_phi on Z axis + + // Momentum in beam frame for heavy particle + G4ThreeVector momentum_kine4_beam(sin(Theta4) * cos(phi + pi), + sin(Theta4) * sin(phi + pi), cos(Theta4)); + // Momentum in World frame + G4ThreeVector momentum_kine4_world = momentum_kine4_beam; + momentum_kine4_world.rotate(Beam_theta, + V); // rotation of Beam_theta on Y axis + momentum_kine4_world.rotate(Beam_phi, ZZ); // rotation of Beam_phi on Z axis + + // Emitt secondary + if (m_Reaction.GetShoot3()) { + G4DynamicParticle particle3(LightName, momentum_kine3_world, Energy3); + fastStep.CreateSecondaryTrack(particle3, localPosition, time); + } + + if (m_Reaction.GetShoot4()) { + G4DynamicParticle particle4(HeavyName, momentum_kine4_world, Energy4); + fastStep.CreateSecondaryTrack(particle4, localPosition, time); + } + + /////////////////////////////////////// + ///// Emitted particle Parameters ///// + /////////////////////////////////////// + // Names 3 and 4// + m_ReactionConditions->SetParticleName(LightName->GetParticleName()); + m_ReactionConditions->SetParticleName(HeavyName->GetParticleName()); + // Angle 3 and 4 // + m_ReactionConditions->SetTheta(Theta3 / deg); + m_ReactionConditions->SetTheta(Theta4 / deg); + + m_ReactionConditions->SetPhi(phi / deg); + if ((phi + pi) / deg > 360) + m_ReactionConditions->SetPhi((phi - pi) / deg); + else + m_ReactionConditions->SetPhi((phi + pi) / deg); + + // Energy 3 and 4 // + m_ReactionConditions->SetKineticEnergy(Energy3); + m_ReactionConditions->SetKineticEnergy(Energy4); + // ThetaCM and Ex// + m_ReactionConditions->SetThetaCM(m_Reaction.GetThetaCM() / deg); + m_ReactionConditions->SetExcitationEnergy3(m_Reaction.GetExcitation3()); + m_ReactionConditions->SetExcitationEnergy4(m_Reaction.GetExcitation4()); + // Momuntum X 3 and 4 // + m_ReactionConditions->SetMomentumDirectionX(momentum_kine3_world.x()); + m_ReactionConditions->SetMomentumDirectionX(momentum_kine4_world.x()); + // Momuntum Y 3 and 4 // + m_ReactionConditions->SetMomentumDirectionY(momentum_kine3_world.y()); + m_ReactionConditions->SetMomentumDirectionY(momentum_kine4_world.y()); + // Momuntum Z 3 and 4 // + m_ReactionConditions->SetMomentumDirectionZ(momentum_kine3_world.z()); + m_ReactionConditions->SetMomentumDirectionZ(momentum_kine4_world.z()); + + }// end if TwoBodyReaction + + else if (m_ReactionType=="QFSReaction" ) { + + //////Define the kind of particle to shoot//////// + // A --> T ==> B + (c -> T) => B + 1 + 2 + + int Light1_Z = m_QFS.GetNucleus1()->GetZ(); + int Light1_A = m_QFS.GetNucleus1()->GetA(); + int Light2_Z = m_QFS.GetNucleus2()->GetZ(); + int Light2_A = m_QFS.GetNucleus2()->GetA(); + + static G4IonTable* IonTable + = G4ParticleTable::GetParticleTable()->GetIonTable(); + + G4ParticleDefinition* Light1Name; + G4ParticleDefinition* Light2Name; + + if (Light1_Z == 0 && Light1_A == 1) // neutron is special case + { + Light1Name = G4Neutron::Definition(); + } else { + Light1Name = IonTable->GetIon(Light1_Z, Light1_A); + } + + if (Light2_Z == 0 && Light2_A == 1) // neutron is special case + { + Light2Name = G4Neutron::Definition(); + } else { + Light2Name = IonTable->GetIon(Light2_Z, Light2_A); + } + + // Nucleus B + G4int Heavy_Z = m_QFS.GetNucleusB()->GetZ(); + G4int Heavy_A = m_QFS.GetNucleusB()->GetA(); + + G4ParticleDefinition* HeavyName; + HeavyName = IonTable->GetIon(Heavy_Z, Heavy_A); + + // Set the Energy of the reaction + m_QFS.SetBeamEnergy(reac_energy); + + double Beam_theta = pdirection.theta(); + double Beam_phi = pdirection.phi(); + + + ///////////////////////////////////////////////////////////////// + ///// Angles for emitted particles following Cross Section ////// + ///// Angles are in the beam frame ////// + ///////////////////////////////////////////////////////////////// + + // Shoot and Set a Random ThetaCM + double theta = G4RandFlat::shoot() * pi; + double phi = G4RandFlat::shoot() * 2. * pi - pi; //rand in [-pi,pi] + m_QFS.SetThetaCM(theta); + m_QFS.SetPhiCM(phi); + + // Shoot and set internal momentum for the removed cluster + // if a momentum Sigma is given then shoot in 3 indep. Gaussians + // if input files are given for distributions use them instead + m_QFS.ShootInternalMomentum(); + + ////////////////////////////////////////////////// + ///// Momentum and angles from kinematics ///// + ////////////////////////////////////////////////// + // Variable where to store results + double Theta1, Phi1, TKE1, Theta2, Phi2, TKE2, ThetaB, PhiB, TKEB; + + // Compute Kinematic using previously defined ThetaCM + m_QFS.KineRelativistic(Theta1, Phi1, TKE1, Theta2, Phi2, TKE2); + + G4ThreeVector U(1, 0, 0); + G4ThreeVector V(0, 1, 0); + G4ThreeVector ZZ(0, 0, 1); + + // Momentum in beam and world frame for light particle 1 + G4ThreeVector momentum_kine1_beam(sin(Theta1) * cos(Phi1), + sin(Theta1) * sin(Phi1), cos(Theta1)); + G4ThreeVector momentum_kine1_world = momentum_kine1_beam; + momentum_kine1_world.rotate(Beam_theta, V); // rotation of Beam_theta on Y axis + momentum_kine1_world.rotate(Beam_phi, ZZ); // rotation of Beam_phi on Z axis + + // Momentum in beam and world frame for light particle 2 + G4ThreeVector momentum_kine2_beam(sin(Theta2) * cos(Phi2), + sin(Theta2) * sin(Phi2), cos(Theta2)); + G4ThreeVector momentum_kine2_world = momentum_kine2_beam; + momentum_kine2_world.rotate(Beam_theta, V); // rotation of Beam_theta on Y axis + momentum_kine2_world.rotate(Beam_phi, ZZ); // rotation of Beam_phi on Z axis + + // Momentum in beam and world frame for heavy residual + // + //G4ThreeVector momentum_kineB_beam(sin(ThetaB) * cos(PhiB + pi), + // sin(ThetaB) * sin(PhiB + pi), cos(ThetaB)); + //G4ThreeVector momentum_kineB_world = momentum_kineB_beam; + //momentum_kineB_world.rotate(Beam_theta, V); // rotation of Beam_theta on Y axis + //momentum_kineB_world.rotate(Beam_phi, ZZ); // rotation of Beam_phi on Z axis + + TLorentzVector* P_A = m_QFS.GetEnergyImpulsionLab_A(); + TLorentzVector* P_B = m_QFS.GetEnergyImpulsionLab_B(); + + G4ThreeVector momentum_kineB_beam( P_B->Px(), P_B->Py(), P_B->Pz() ); + momentum_kineB_beam = momentum_kineB_beam.unit(); + TKEB = P_B->Energy() - m_QFS.GetNucleusB()->Mass(); + G4ThreeVector momentum_kineB_world = momentum_kineB_beam; + momentum_kineB_world.rotate(Beam_theta, V); // rotation of Beam_theta on Y axis + momentum_kineB_world.rotate(Beam_phi, ZZ); // rotation of Beam_phi on Z axis + + ThetaB = P_B->Angle(P_A->Vect()); + if (ThetaB < 0) ThetaB += M_PI; + PhiB = M_PI + P_B->Vect().Phi(); + if (fabs(PhiB) < 1e-6) PhiB = 0; + + + // Emitt secondary + if (m_QFS.GetShoot1()) { + G4DynamicParticle particle1(Light1Name, momentum_kine1_world, TKE1); + fastStep.CreateSecondaryTrack(particle1, localPosition, time); + } + + if (m_QFS.GetShoot2()) { + G4DynamicParticle particle2(Light2Name, momentum_kine2_world, TKE2); + fastStep.CreateSecondaryTrack(particle2, localPosition, time); + } + if (m_QFS.GetShootB()) { + G4DynamicParticle particleB(HeavyName, momentum_kineB_world, TKEB); + fastStep.CreateSecondaryTrack(particleB, localPosition, time); + } + + /////////////////////////////////// + ///// Reaction Condition Save ///// + /////////////////////////////////// + m_ReactionConditions->SetBeamParticleName( + PrimaryTrack->GetParticleDefinition()->GetParticleName()); + m_ReactionConditions->SetBeamReactionEnergy(reac_energy); + m_ReactionConditions->SetVertexPositionX(localPosition.x()); + m_ReactionConditions->SetVertexPositionY(localPosition.y()); + m_ReactionConditions->SetVertexPositionZ(localPosition.z()); + m_ReactionConditions->SetBeamEmittanceTheta( + PrimaryTrack->GetMomentumDirection().theta() / deg); + m_ReactionConditions->SetBeamEmittancePhi( + PrimaryTrack->GetMomentumDirection().phi() / deg); + m_ReactionConditions->SetBeamEmittanceThetaX( + PrimaryTrack->GetMomentumDirection().angle(U) / deg); + m_ReactionConditions->SetBeamEmittancePhiY( + PrimaryTrack->GetMomentumDirection().angle(V) / deg); + + // Names 1,2 and B// + m_ReactionConditions->SetParticleName(Light1Name->GetParticleName()); + m_ReactionConditions->SetParticleName(Light2Name->GetParticleName()); + m_ReactionConditions->SetParticleName(HeavyName->GetParticleName()); + // Angle 1,2 and B // + m_ReactionConditions->SetTheta(Theta1 / deg); + m_ReactionConditions->SetTheta(Theta2 / deg); + m_ReactionConditions->SetTheta(ThetaB / deg); + m_ReactionConditions->SetPhi(Phi1 / deg); + m_ReactionConditions->SetPhi(Phi2 / deg); + m_ReactionConditions->SetPhi(PhiB / deg); + // Energy 1,2 and B // + m_ReactionConditions->SetKineticEnergy(TKE1); + m_ReactionConditions->SetKineticEnergy(TKE2); + m_ReactionConditions->SetKineticEnergy(TKEB); + // ThetaCM, Ex and Internal Momentum of removed cluster// + m_ReactionConditions->SetThetaCM(m_QFS.GetThetaCM() / deg); + m_ReactionConditions->SetInternalMomentum(m_QFS.GetInternalMomentum()); + //m_ReactionConditions->SetExcitationEnergy3(m_QFS.GetExcitation3()); + //m_ReactionConditions->SetExcitationEnergy4(m_QFS.GetExcitation4()); + // Momuntum X 1,2 and B // + m_ReactionConditions->SetMomentumDirectionX(momentum_kine1_world.x()); + m_ReactionConditions->SetMomentumDirectionX(momentum_kine2_world.x()); + m_ReactionConditions->SetMomentumDirectionX(momentum_kineB_world.x()); + // Momuntum Y 1,2 and B // + m_ReactionConditions->SetMomentumDirectionY(momentum_kine1_world.y()); + m_ReactionConditions->SetMomentumDirectionY(momentum_kine2_world.y()); + m_ReactionConditions->SetMomentumDirectionY(momentum_kineB_world.y()); + // Momuntum Z 1,2 and B // + m_ReactionConditions->SetMomentumDirectionZ(momentum_kine1_world.z()); + m_ReactionConditions->SetMomentumDirectionZ(momentum_kine2_world.z()); + m_ReactionConditions->SetMomentumDirectionZ(momentum_kineB_world.z()); + + } +} +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +// Return the slow down beam in given thickness of material +double NPS::BeamReaction::SlowDownBeam(const G4ParticleDefinition* Beam, + double IncidentEnergy, + double Thickness, + G4Material* Material){ + + + if(Beam->GetParticleName()=="neutron"){ + return IncidentEnergy; + } + + double dedx,de; + int NbSlice = 100; + static G4EmCalculator emCalculator; + + if(Thickness!=0){ + for (G4int i = 0; i < NbSlice; i++){ + dedx = emCalculator.ComputeTotalDEDX(IncidentEnergy, Beam, Material); + de = dedx * Thickness / NbSlice; + IncidentEnergy -= de; + if(IncidentEnergy<0){ + IncidentEnergy = 0; + break; + } } + } + + return IncidentEnergy; + } + diff --git a/NPSimulation/Process/BeamReaction.hh b/NPSimulation/Process/BeamReaction.hh index f5c9a41d28ea2248c90d17cb8aee2cadff4c0fb7..2d1dc6336f7d442b22ba2587a5166f8fff4d6b65 100644 --- a/NPSimulation/Process/BeamReaction.hh +++ b/NPSimulation/Process/BeamReaction.hh @@ -48,12 +48,16 @@ namespace NPS{ NPL::QFS m_QFS; string m_BeamName; string m_ReactionType; - double m_PreviousEnergy; - double m_PreviousLength; bool m_active;// is the process active + bool m_shoot; double m_StepSize; + double m_Z; + double m_rand; + double m_length; int m_Parent_ID; - + double SlowDownBeam(const G4ParticleDefinition* Beam, double IncidentEnergy, double Thickness,G4Material* Material); + + private: TReactionConditions* m_ReactionConditions; diff --git a/NPSimulation/Process/CMakeLists.txt b/NPSimulation/Process/CMakeLists.txt index 2f9dfe901fb7b2f43bba7fa149cd3c290fc15f4d..7f9dfac741476858b29702be2ce1a94ca1fbf255 100644 --- a/NPSimulation/Process/CMakeLists.txt +++ b/NPSimulation/Process/CMakeLists.txt @@ -1,6 +1,6 @@ -if(Geant4_VERSION_MAJOR GREATER_EQUAL 10) - if(Geant4_VERSION_MINOR GREATER_EQUAL 5) +if(Geant4_VERSION_MAJOR GREATER 9) + if(Geant4_VERSION_MINOR GREATER 4) message("Compiling with NeutronHPphysics") add_library(NPSProcess SHARED Decay.cc BeamReaction.cc FastDriftElectron.cc NPIonIonInelasticPhysic.cc PhysicsList.cc G4DriftElectron.cc G4IonizationWithDE.cc G4DriftElectronPhysics.cc G4DEAbsorption.cc G4DEAmplification.cc G4DETransport.cc menate_R.cc NeutronHPphysics.cc NeutronHPMessenger.cc) diff --git a/NPSimulation/Process/Decay.cc b/NPSimulation/Process/Decay.cc index 442d98b6819d69154e36a921163f64e6dd17ff8a..30c82cdd4cfc5a142ba3456f28abc6608a4567b1 100644 --- a/NPSimulation/Process/Decay.cc +++ b/NPSimulation/Process/Decay.cc @@ -61,8 +61,12 @@ void Decay::ReadConfiguration(){ m_Decay.ReadConfiguration(input); std::set<std::string> Mother = m_Decay.GetAllMotherName(); std::set<std::string>::iterator it ; - for(it = Mother.begin() ; it != Mother.end() ; it++) + for(it = Mother.begin() ; it != Mother.end() ; it++){ + // ground state name, e.g. deuteron m_MotherName.insert(NPL::ChangeNameToG4Standard(*it)); + // excited state name e.g. H2 + m_MotherName.insert(NPL::ChangeNameToG4Standard(*it,true)); + } } //////////////////////////////////////////////////////////////////////////////// @@ -130,6 +134,7 @@ void Decay::DoIt(const G4FastTrack& fastTrack,G4FastStep& fastStep){ G4ParticleDefinition* DaughterDef; unsigned int size = Daughter.size(); + if(size == 0) return; for(unsigned int i = 0 ; i < size ; i++){ diff --git a/NPSimulation/Simulation.cc b/NPSimulation/Simulation.cc index ed862a21df62f611f1149d2c3d1cc51f136af25e..d27003e1bf72fdd71df6eb0cedae78d1676cc28c 100644 --- a/NPSimulation/Simulation.cc +++ b/NPSimulation/Simulation.cc @@ -12,13 +12,9 @@ #include "G4UItcsh.hh" #include "G4VisManager.hh" -#ifdef G4VIS_USE #include "G4VisExecutive.hh" -#endif -#ifdef G4UI_USE #include "G4UIExecutive.hh" -#endif // G4 local source #include "DetectorConstruction.hh" @@ -104,9 +100,7 @@ int main(int argc, char** argv){ // Get the pointer to the User Interface manager G4cout << "//////////// Starting UI ////////////"<< endl; G4UImanager* UImanager = G4UImanager::GetUIpointer(); -#ifdef G4UI_USE G4UIExecutive* ui = new G4UIExecutive(argc, argv); -#endif /////////////////////////////////////////////////////////////// @@ -131,21 +125,19 @@ int main(int argc, char** argv){ G4VisManager* visManager=NULL; -#ifdef G4UI_USE if(!OptionManager->GetG4BatchMode()){ string Path_Macro = getenv("NPTOOL"); Path_Macro+="/NPSimulation/ressources/macro/"; UImanager->ApplyCommand("/control/execute " +Path_Macro+"verbose.mac"); - #ifdef G4VIS_USE UImanager->ApplyCommand("/control/execute " +Path_Macro+"aliases.mac"); visManager = new G4VisExecutive("Quiet"); visManager->Initialize(); UImanager->ApplyCommand("/control/execute " +Path_Macro+"vis.mac"); - #endif if (ui->IsGUI()){ UImanager->ApplyCommand("/control/execute " +Path_Macro+"gui.mac"); } + #ifdef __APPLE__ string command= "osascript "; command+= getenv("NPTOOL"); @@ -155,7 +147,7 @@ int main(int argc, char** argv){ #endif } else{// if batch mode do not accumulate any track - UImanager->ApplyCommand("/vis/scene/endOfEventAction accumulate 0"); + UImanager->ApplyCommand("/vis/scene/endOfEventAction accumulate 0"); } // Execute user macro if(!OptionManager->IsDefault("G4MacroPath")){ @@ -168,12 +160,9 @@ int main(int argc, char** argv){ delete ui; -#endif -#ifdef G4VIS_USE if(visManager) delete visManager; -#endif /////////////////////////////////////////////////////////////// ////////////////////// Job termination //////////////////////// diff --git a/Projects/Catana/Analysis.cxx b/Projects/Catana/Analysis.cxx new file mode 100644 index 0000000000000000000000000000000000000000..e36aeb67528fbbdb43336123f2cbfca145e85a62 --- /dev/null +++ b/Projects/Catana/Analysis.cxx @@ -0,0 +1,68 @@ +/***************************************************************************** + * 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: XAUTHORX contact address: XMAILX * + * * + * Creation Date : XMONTHX XYEARX * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class describe Catana analysis project * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + *****************************************************************************/ + +#include<iostream> +using namespace std; +#include"Analysis.h" +#include"NPAnalysisFactory.h" +#include"NPDetectorManager.h" +//////////////////////////////////////////////////////////////////////////////// +Analysis::Analysis(){ +} +//////////////////////////////////////////////////////////////////////////////// +Analysis::~Analysis(){ +} + +//////////////////////////////////////////////////////////////////////////////// +void Analysis::Init(){ + Catana= (TCatanaPhysicsPhysics*) m_DetectorManager->GetDetector("Catana"); +} + +//////////////////////////////////////////////////////////////////////////////// +void Analysis::TreatEvent(){ +} + +//////////////////////////////////////////////////////////////////////////////// +void Analysis::End(){ +} + + +//////////////////////////////////////////////////////////////////////////////// +// Construct Method to be pass to the DetectorFactory // +//////////////////////////////////////////////////////////////////////////////// +NPL::VAnalysis* Analysis::Construct(){ + return (NPL::VAnalysis*) new Analysis(); +} + +//////////////////////////////////////////////////////////////////////////////// +// Registering the construct method to the factory // +//////////////////////////////////////////////////////////////////////////////// +extern "C"{ +class proxy{ + public: + proxy(){ + NPL::AnalysisFactory::getInstance()->SetConstructor(Analysis::Construct); + } +}; + +proxy p; +} + diff --git a/Projects/Catana/Analysis.h b/Projects/Catana/Analysis.h new file mode 100644 index 0000000000000000000000000000000000000000..a63ed81e20396ebf53ba687f5d18b0d8fd59696a --- /dev/null +++ b/Projects/Catana/Analysis.h @@ -0,0 +1,42 @@ +#ifndef Analysis_h +#define Analysis_h +/***************************************************************************** + * 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: XAUTHORX contact address: XMAILX * + * * + * Creation Date : XMONTHX XYEARX * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class describe Catana analysis project * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + *****************************************************************************/ + +#include"NPVAnalysis.h" +#include"TCatanaPhysics.h" +class Analysis: public NPL::VAnalysis{ + public: + Analysis(); + ~Analysis(); + + public: + void Init(); + void TreatEvent(); + void End(); + + static NPL::VAnalysis* Construct(); + + private: + TCatanaPhysics* Catana; + +}; +#endif diff --git a/Projects/Catana/CATANAPLUS_Detectors.csv b/Projects/Catana/CATANAPLUS_Detectors.csv new file mode 100644 index 0000000000000000000000000000000000000000..d4ff3b87fde5d003f43a9a22f445bf589ed7ac13 --- /dev/null +++ b/Projects/Catana/CATANAPLUS_Detectors.csv @@ -0,0 +1,141 @@ +ID,DetectorType,Layer,X,Y,Z,Theta,Phi +1, 1, 1, -38.4258, 242.611, 26.5, 84.75, 9 +2, 1, 1, -111.516, 218.862, 26.5, 84.75, 27 +3, 1, 1, -173.69, 173.69, 26.5, 84.75, 45 +4, 1, 1, -218.862, 111.516, 26.5, 84.75, 63 +5, 1, 1, -242.611, 38.4258, 26.5, 84.75, 81 +6, 1, 1, -242.611, -38.4258, 26.5, 84.75, 99 +7, 1, 1, -218.862, -111.516, 26.5, 84.75, 117 +8, 1, 1, -173.69, -173.69, 26.5, 84.75, 135 +9, 1, 1, -111.516, -218.862, 26.5, 84.75, 153 +10, 1, 1, -38.4258, -242.611, 26.5, 84.75, 171 +11, 1, 1, 38.4258, -242.611, 26.5, 84.75, 189 +12, 1, 1, 111.516, -218.862, 26.5, 84.75, 207 +13, 1, 1, 173.69, -173.69, 26.5, 84.75, 225 +14, 1, 1, 218.862, -111.516, 26.5, 84.75, 243 +15, 1, 1, 242.611, -38.4258, 26.5, 84.75, 261 +16, 1, 1, 242.611, 38.4258, 26.5, 84.75, 279 +17, 1, 1, 218.862, 111.516, 26.5, 84.75, 297 +18, 1, 1, 173.69, 173.69, 26.5, 84.75, 315 +19, 1, 1, 111.516, 218.862, 26.5, 84.75, 333 +20, 1, 1, 38.4258, 242.611, 26.5, 84.75, 351 +21, 1, 2, -39.4712, 249.212, 74.7, 74.25, 9 +22, 1, 2, -114.55, 224.817, 74.7, 74.25, 27 +23, 1, 2, -178.416, 178.416, 74.7, 74.25, 45 +24, 1, 2, -224.817, 114.55, 74.7, 74.25, 63 +25, 1, 2, -249.212, 39.4712, 74.7, 74.25, 81 +26, 1, 2, -249.212, -39.4712, 74.7, 74.25, 99 +27, 1, 2, -224.817, -114.55, 74.7, 74.25, 117 +28, 1, 2, -178.416, -178.416, 74.7, 74.25, 135 +29, 1, 2, -114.55, -224.817, 74.7, 74.25, 153 +30, 1, 2, -39.4712, -249.212, 74.7, 74.25, 171 +31, 1, 2, 39.4712, -249.212, 74.7, 74.25, 189 +32, 1, 2, 114.55, -224.817, 74.7, 74.25, 207 +33, 1, 2, 178.416, -178.416, 74.7, 74.25, 225 +34, 1, 2, 224.817, -114.55, 74.7, 74.25, 243 +35, 1, 2, 249.212, -39.4712, 74.7, 74.25, 261 +36, 1, 2, 249.212, 39.4712, 74.7, 74.25, 279 +37, 1, 2, 224.817, 114.55, 74.7, 74.25, 297 +38, 1, 2, 178.416, 178.416, 74.7, 74.25, 315 +39, 1, 2, 114.55, 224.817, 74.7, 74.25, 333 +40, 1, 2, 39.4712, 249.212, 74.7, 74.25, 351 +41, 2, 3, -39.34, 248.383, 123.2, 64, 9 +42, 2, 3, -114.169, 224.069, 123.2, 64, 27 +43, 2, 3, -177.823, 177.823, 123.2, 64, 45 +44, 2, 3, -224.069, 114.169, 123.2, 64, 63 +45, 2, 3, -248.383, 39.34, 123.2, 64, 81 +46, 2, 3, -248.383, -39.34, 123.2, 64, 99 +47, 2, 3, -224.069, -114.169, 123.2, 64, 117 +48, 2, 3, -177.823, -177.823, 123.2, 64, 135 +49, 2, 3, -114.169, -224.069, 123.2, 64, 153 +50, 2, 3, -39.34, -248.383, 123.2, 64, 171 +51, 2, 3, 39.34, -248.383, 123.2, 64, 189 +52, 2, 3, 114.169, -224.069, 123.2, 64, 207 +53, 2, 3, 177.823, -177.823, 123.2, 64, 225 +54, 2, 3, 224.069, -114.169, 123.2, 64, 243 +55, 2, 3, 248.383, -39.34, 123.2, 64, 261 +56, 2, 3, 248.383, 39.34, 123.2, 64, 279 +57, 2, 3, 224.069, 114.169, 123.2, 64, 297 +58, 2, 3, 177.823, 177.823, 123.2, 64, 315 +59, 2, 3, 114.169, 224.069, 123.2, 64, 333 +60, 2, 3, 39.34, 248.383, 123.2, 64, 351 +61, 2, 4, -37.4072, 236.18, 168.2, 54, 9 +62, 2, 4, -108.56, 213.061, 168.2, 54, 27 +63, 2, 4, -169.086, 169.086, 168.2, 54, 45 +64, 2, 4, -213.061, 108.56, 168.2, 54, 63 +65, 2, 4, -236.18, 37.4072, 168.2, 54, 81 +66, 2, 4, -236.18, -37.4072, 168.2, 54, 99 +67, 2, 4, -213.061, -108.56, 168.2, 54, 117 +68, 2, 4, -169.086, -169.086, 168.2, 54, 135 +69, 2, 4, -108.56, -213.061, 168.2, 54, 153 +70, 2, 4, -37.4072, -236.18, 168.2, 54, 171 +71, 2, 4, 37.4072, -236.18, 168.2, 54, 189 +72, 2, 4, 108.56, -213.061, 168.2, 54, 207 +73, 2, 4, 169.086, -169.086, 168.2, 54, 225 +74, 2, 4, 213.061, -108.56, 168.2, 54, 243 +75, 2, 4, 236.18, -37.4072, 168.2, 54, 261 +76, 2, 4, 236.18, 37.4072, 168.2, 54, 279 +77, 2, 4, 213.061, 108.56, 168.2, 54, 297 +78, 2, 4, 169.086, 169.086, 168.2, 54, 315 +79, 2, 4, 108.56, 213.061, 168.2, 54, 333 +80, 2, 4, 37.4072, 236.18, 168.2, 54, 351 +81, 3, 5, -33.7152, 212.87, 211.3, 43.5, 9 +82, 3, 5, -97.8454, 192.032, 211.3, 43.5, 27 +83, 3, 5, -152.398, 152.398, 211.3, 43.5, 45 +84, 3, 5, -192.032, 97.8454, 211.3, 43.5, 63 +85, 3, 5, -212.87, 33.7152, 211.3, 43.5, 81 +86, 3, 5, -212.87, -33.7152, 211.3, 43.5, 99 +87, 3, 5, -192.032, -97.8454, 211.3, 43.5, 117 +88, 3, 5, -152.398, -152.398, 211.3, 43.5, 135 +89, 3, 5, -97.8454, -192.032, 211.3, 43.5, 153 +90, 3, 5, -33.7152, -212.87, 211.3, 43.5, 171 +91, 3, 5, 33.7152, -212.87, 211.3, 43.5, 189 +92, 3, 5, 97.8454, -192.032, 211.3, 43.5, 207 +93, 3, 5, 152.398, -152.398, 211.3, 43.5, 225 +94, 3, 5, 192.032, -97.8454, 211.3, 43.5, 243 +95, 3, 5, 212.87, -33.7152, 211.3, 43.5, 261 +96, 3, 5, 212.87, 33.7152, 211.3, 43.5, 279 +97, 3, 5, 192.032, 97.8454, 211.3, 43.5, 297 +98, 3, 5, 152.398, 152.398, 211.3, 43.5, 315 +99, 3, 5, 97.8454, 192.032, 211.3, 43.5, 333 +100, 3, 5, 33.7152, 212.87, 211.3, 43.5, 351 +101, 4, 6, -28.1643, 177.822, 250, 32.5, 9 +102, 4, 6, -81.736, 160.416, 250, 32.5, 27 +103, 4, 6, -127.307, 127.307, 250, 32.5, 45 +104, 4, 6, -160.416, 81.736, 250, 32.5, 63 +105, 4, 6, -177.822, 28.1643, 250, 32.5, 81 +106, 4, 6, -177.822, -28.1643, 250, 32.5, 99 +107, 4, 6, -160.416, -81.736, 250, 32.5, 117 +108, 4, 6, -127.307, -127.307, 250, 32.5, 135 +109, 4, 6, -81.736, -160.416, 250, 32.5, 153 +110, 4, 6, -28.1643, -177.822, 250, 32.5, 171 +111, 4, 6, 28.1643, -177.822, 250, 32.5, 189 +112, 4, 6, 81.736, -160.416, 250, 32.5, 207 +113, 4, 6, 127.307, -127.307, 250, 32.5, 225 +114, 4, 6, 160.416, -81.736, 250, 32.5, 243 +115, 4, 6, 177.822, -28.1643, 250, 32.5, 261 +116, 4, 6, 177.822, 28.1643, 250, 32.5, 279 +117, 4, 6, 160.416, 81.736, 250, 32.5, 297 +118, 4, 6, 127.307, 127.307, 250, 32.5, 315 +119, 4, 6, 81.736, 160.416, 250, 32.5, 333 +120, 4, 6, 28.1643, 177.822, 250, 32.5, 351 +121, 5, 7, -21.105, 133.252, 278.357, 21.5, 9 +122, 5, 7, -61.2492, 120.208, 278.357, 21.5, 27 +123, 5, 7, -95.3979, 95.3979, 278.357, 21.5, 45 +124, 5, 7, -120.208, 61.2492, 278.357, 21.5, 63 +125, 5, 7, -133.252, 21.105, 278.357, 21.5, 81 +126, 5, 7, -133.252, -21.105, 278.357, 21.5, 99 +127, 5, 7, -120.208, -61.2492, 278.357, 21.5, 117 +128, 5, 7, -95.3979, -95.3979, 278.357, 21.5, 135 +129, 5, 7, -61.2492, -120.208, 278.357, 21.5, 153 +130, 5, 7, -21.105, -133.252, 278.357, 21.5, 171 +131, 5, 7, 21.105, -133.252, 278.357, 21.5, 189 +132, 5, 7, 61.2492, -120.208, 278.357, 21.5, 207 +133, 5, 7, 95.3979, -95.3979, 278.357, 21.5, 225 +134, 5, 7, 120.208, -61.2492, 278.357, 21.5, 243 +135, 5, 7, 133.252, -21.105, 278.357, 21.5, 261 +136, 5, 7, 133.252, 21.105, 278.357, 21.5, 279 +137, 5, 7, 120.208, 61.2492, 278.357, 21.5, 297 +138, 5, 7, 95.3979, 95.3979, 278.357, 21.5, 315 +139, 5, 7, 61.2492, 120.208, 278.357, 21.5, 333 +140, 5, 7, 21.105, 133.252, 278.357, 21.5, 351 diff --git a/Projects/Catana/CMakeLists.txt b/Projects/Catana/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..22c74affdfc45019bdda2594f8439c52d4ab97ec --- /dev/null +++ b/Projects/Catana/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required (VERSION 2.8) +# Setting the policy to match Cmake version +cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}) +# include the default NPAnalysis cmake file +include("../../NPLib/ressources/CMake/NPAnalysis.cmake") diff --git a/Projects/Catana/Catana.detector b/Projects/Catana/Catana.detector new file mode 100644 index 0000000000000000000000000000000000000000..650e5266bcb00ba3de5a316eef646fdb05d3fa46 --- /dev/null +++ b/Projects/Catana/Catana.detector @@ -0,0 +1,62 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Target + THICKNESS= 10 micrometer + RADIUS= 20 mm + MATERIAL= CD2 + ANGLE= 0 deg + X= 0 mm + Y= 0 mm + Z= 0 mm + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Catana CSV + Path= Catana.csv + Pos= 0 0 500 mm + Rshift= 70 micrometer + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%Catana Detector +% X= 100 mm +% Y= 100 mm +% Z= 100 mm +% Theta= 0 deg +% Phi= 0 deg +% ID= 1 +% Type= 1 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%Catana Detector +% X= 300 mm +% Y= 300 mm +% Z= 300 mm +% Theta= 0 deg +% Phi= 0 deg +% ID= 1 +% Type= 2 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%Catana Detector +% X= 600 mm +% Y= 600 mm +% Z= 600 mm +% Theta= 0 deg +% Phi= 0 deg +% ID= 1 +% Type= 3 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%Catana Detector +% X= 900 mm +% Y= 900 mm +% Z= 900 mm +% Theta= 0 deg +% Phi= 0 deg +% ID= 1 +% Type= 4 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%Catana Detector +% X= 1200 mm +% Y= 1200 mm +% Z= 1200 mm +% Theta= 0 deg +% Phi= 0 deg +% ID= 1 +% Type= 5 +% diff --git a/Projects/MUGAST/16Odp17O_870keV_12.reaction b/Projects/MUGAST/16Odp17O_870keV_12.reaction new file mode 100644 index 0000000000000000000000000000000000000000..e12027a95dde91ab03c60e67d5623de4e7f5059b --- /dev/null +++ b/Projects/MUGAST/16Odp17O_870keV_12.reaction @@ -0,0 +1,30 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%% Reaction file: 56Ni(d,p)57Ni at VAMOS-AGATA %%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Beam + Particle= 16O + Energy= 96 MeV + SigmaEnergy= 0 MeV + SigmaX= 0 mm + SigmaY= 0 mm + SigmaThetaX= 0.0 deg + SigmaPhiY= 0.0 deg + MeanThetaX= 0 mm + MeanPhiY= 0 mm + MeanX= 0 mm + MeanY= 0 mm + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +TwoBodyReaction + Beam= 16O + Target= 2H + Light= 1H + Heavy= 17O + ExcitationEnergyLight= 0.0 MeV + ExcitationEnergyHeavy= 0.870 MeV + CrossSectionPath= 16Odp17O_s12_6AMeV.dat CS + %CrossSectionPath= flat.txt CS + ShootLight= 1 + ShootHeavy= 1 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/Projects/MUGAST/16Odp17O_gs.reaction b/Projects/MUGAST/16Odp17O_gs.reaction new file mode 100644 index 0000000000000000000000000000000000000000..2fdc85b1b2c1449e24eb1e0963e110e06817bf10 --- /dev/null +++ b/Projects/MUGAST/16Odp17O_gs.reaction @@ -0,0 +1,29 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%% Reaction file: 56Ni(d,p)57Ni at VAMOS-AGATA %%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Beam + Particle= 16O + Energy= 96 MeV + SigmaEnergy= 0 MeV + SigmaX= 0 mm + SigmaY= 0 mm + SigmaThetaX= 0.0 deg + SigmaPhiY= 0.0 deg + MeanThetaX= 0 mm + MeanPhiY= 0 mm + MeanX= 0 mm + MeanY= 0 mm + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +TwoBodyReaction + Beam= 16O + Target= 2H + Light= 1H + Heavy= 17O + ExcitationEnergyLight= 0.0 MeV + ExcitationEnergyHeavy= 0.0 MeV + CrossSectionPath= 16Odp17O_s12_6AMeV.dat CS + ShootLight= 1 + ShootHeavy= 1 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/Projects/MUGAST/16Odp17O_s12_6AMeV.dat b/Projects/MUGAST/16Odp17O_s12_6AMeV.dat new file mode 100644 index 0000000000000000000000000000000000000000..81dcbecd1a9eedbb800b9e3841a5b0274e48207a --- /dev/null +++ b/Projects/MUGAST/16Odp17O_s12_6AMeV.dat @@ -0,0 +1,181 @@ + 0.00 1.914689E+02 + 1.00 1.903373E+02 + 2.00 1.869800E+02 + 3.00 1.815069E+02 + 4.00 1.740951E+02 + 5.00 1.649792E+02 + 6.00 1.544396E+02 + 7.00 1.427886E+02 + 8.00 1.303562E+02 + 9.00 1.174749E+02 + 10.00 1.044670E+02 + 11.00 9.163196E+01 + 12.00 7.923714E+01 + 13.00 6.751044E+01 + 14.00 5.663581E+01 + 15.00 4.675114E+01 + 16.00 3.794856E+01 + 17.00 3.027664E+01 + 18.00 2.374425E+01 + 19.00 1.832545E+01 + 20.00 1.396521E+01 + 21.00 1.058544E+01 + 22.00 8.091037E+00 + 23.00 6.375645E+00 + 24.00 5.326967E+00 + 25.00 4.831442E+00 + 26.00 4.778200E+00 + 27.00 5.062263E+00 + 28.00 5.586985E+00 + 29.00 6.265784E+00 + 30.00 7.023207E+00 + 31.00 7.795429E+00 + 32.00 8.530265E+00 + 33.00 9.186782E+00 + 34.00 9.734620E+00 + 35.00 1.015309E+01 + 36.00 1.043010E+01 + 37.00 1.056108E+01 + 38.00 1.054776E+01 + 39.00 1.039707E+01 + 40.00 1.012002E+01 + 41.00 9.730684E+00 + 42.00 9.245242E+00 + 43.00 8.681144E+00 + 44.00 8.056363E+00 + 45.00 7.388755E+00 + 46.00 6.695534E+00 + 47.00 5.992840E+00 + 48.00 5.295413E+00 + 49.00 4.616354E+00 + 50.00 3.966975E+00 + 51.00 3.356727E+00 + 52.00 2.793184E+00 + 53.00 2.282089E+00 + 54.00 1.827444E+00 + 55.00 1.431633E+00 + 56.00 1.095566E+00 + 57.00 8.188420E-01 + 58.00 5.999210E-01 + 59.00 4.362965E-01 + 60.00 3.246654E-01 + 61.00 2.610923E-01 + 62.00 2.411648E-01 + 63.00 2.601375E-01 + 64.00 3.130644E-01 + 65.00 3.949183E-01 + 66.00 5.006971E-01 + 67.00 6.255160E-01 + 68.00 7.646870E-01 + 69.00 9.137842E-01 + 70.00 1.068696E+00 + 71.00 1.225665E+00 + 72.00 1.381317E+00 + 73.00 1.532673E+00 + 74.00 1.677160E+00 + 75.00 1.812607E+00 + 76.00 1.937231E+00 + 77.00 2.049626E+00 + 78.00 2.148737E+00 + 79.00 2.233833E+00 + 80.00 2.304484E+00 + 81.00 2.360527E+00 + 82.00 2.402038E+00 + 83.00 2.429303E+00 + 84.00 2.442784E+00 + 85.00 2.443096E+00 + 86.00 2.430979E+00 + 87.00 2.407270E+00 + 88.00 2.372884E+00 + 89.00 2.328788E+00 + 90.00 2.275983E+00 + 91.00 2.215488E+00 + 92.00 2.148320E+00 + 93.00 2.075485E+00 + 94.00 1.997958E+00 + 95.00 1.916681E+00 + 96.00 1.832548E+00 + 97.00 1.746401E+00 + 98.00 1.659024E+00 + 99.00 1.571140E+00 + 100.00 1.483406E+00 + 101.00 1.396416E+00 + 102.00 1.310700E+00 + 103.00 1.226720E+00 + 104.00 1.144883E+00 + 105.00 1.065532E+00 + 106.00 9.889562E-01 + 107.00 9.153939E-01 + 108.00 8.450342E-01 + 109.00 7.780226E-01 + 110.00 7.144647E-01 + 111.00 6.544303E-01 + 112.00 5.979575E-01 + 113.00 5.450562E-01 + 114.00 4.957125E-01 + 115.00 4.498914E-01 + 116.00 4.075406E-01 + 117.00 3.685935E-01 + 118.00 3.329718E-01 + 119.00 3.005884E-01 + 120.00 2.713494E-01 + 121.00 2.451567E-01 + 122.00 2.219092E-01 + 123.00 2.015054E-01 + 124.00 1.838436E-01 + 125.00 1.688244E-01 + 126.00 1.563506E-01 + 127.00 1.463287E-01 + 128.00 1.386690E-01 + 129.00 1.332863E-01 + 130.00 1.301001E-01 + 131.00 1.290345E-01 + 132.00 1.300181E-01 + 133.00 1.329839E-01 + 134.00 1.378690E-01 + 135.00 1.446138E-01 + 136.00 1.531618E-01 + 137.00 1.634589E-01 + 138.00 1.754528E-01 + 139.00 1.890917E-01 + 140.00 2.043247E-01 + 141.00 2.210998E-01 + 142.00 2.393642E-01 + 143.00 2.590627E-01 + 144.00 2.801377E-01 + 145.00 3.025281E-01 + 146.00 3.261691E-01 + 147.00 3.509911E-01 + 148.00 3.769198E-01 + 149.00 4.038755E-01 + 150.00 4.317730E-01 + 151.00 4.605210E-01 + 152.00 4.900226E-01 + 153.00 5.201749E-01 + 154.00 5.508690E-01 + 155.00 5.819905E-01 + 156.00 6.134197E-01 + 157.00 6.450319E-01 + 158.00 6.766977E-01 + 159.00 7.082841E-01 + 160.00 7.396547E-01 + 161.00 7.706706E-01 + 162.00 8.011912E-01 + 163.00 8.310749E-01 + 164.00 8.601802E-01 + 165.00 8.883668E-01 + 166.00 9.154959E-01 + 167.00 9.414322E-01 + 168.00 9.660438E-01 + 169.00 9.892042E-01 + 170.00 1.010792E+00 + 171.00 1.030695E+00 + 172.00 1.048805E+00 + 173.00 1.065026E+00 + 174.00 1.079269E+00 + 175.00 1.091457E+00 + 176.00 1.101522E+00 + 177.00 1.109409E+00 + 178.00 1.115074E+00 + 179.00 1.118486E+00 + 180.00 1.119625E+00 diff --git a/Projects/MUGAST/Analysis.cxx b/Projects/MUGAST/Analysis.cxx index 30a945f89890ce68e04369fe619584f5a2e6eb3e..81e30e8c51952de9fd5b19c391f844a9f6cffdce 100644 --- a/Projects/MUGAST/Analysis.cxx +++ b/Projects/MUGAST/Analysis.cxx @@ -36,16 +36,29 @@ Analysis::~Analysis(){ //////////////////////////////////////////////////////////////////////////////// void Analysis::Init() { - + if(NPOptionManager::getInstance()->HasDefinition("simulation")){ + cout << "Considering input data as simulation" << endl; + simulation=true; + } + else{ + cout << "Considering input data as real" << endl; + simulation=false; + } agata_zShift=51*mm; // initialize input and output branches + if(simulation){ + Initial = new TInitialConditions(); + ReactionConditions = new TReactionConditions(); + } + InitOutputBranch(); InitInputBranch(); // get MUST2 and Gaspard objects M2 = (TMust2Physics*) m_DetectorManager -> GetDetector("M2Telescope"); MG = (TMugastPhysics*) m_DetectorManager -> GetDetector("Mugast"); - CATS = (TCATSPhysics*) m_DetectorManager->GetDetector("CATSDetector"); + if(!simulation) + CATS = (TCATSPhysics*) m_DetectorManager->GetDetector("CATSDetector"); // get reaction information reaction.ReadConfigurationFile(NPOptionManager::getInstance()->GetReactionFile()); @@ -65,7 +78,13 @@ void Analysis::Init() { LightSi = NPL::EnergyLoss(light+"_Si.G4table","G4Table",100); BeamCD2 = NPL::EnergyLoss(beam+"_"+TargetMaterial+".G4table","G4Table",100); + FinalBeamEnergy = BeamCD2.Slow(OriginalBeamEnergy,TargetThickness*0.5,0); + //FinalBeamEnergy = OriginalBeamEnergy; + cout << "Original beam energy: " << OriginalBeamEnergy << " MeV Mid-target beam energy: " << FinalBeamEnergy << "MeV " << endl; + reaction.SetBeamEnergy(FinalBeamEnergy); + if(WindowsThickness){ + cout << "Cryogenic target with windows" << endl; BeamWindow= new NPL::EnergyLoss(beam+"_"+WindowsMaterial+".G4table","G4Table",100); LightWindow= new NPL::EnergyLoss(light+"_"+WindowsMaterial+".G4table","G4Table",100); } @@ -90,6 +109,7 @@ void Analysis::Init() { Z = 0; dE = 0; BeamDirection = TVector3(0,0,1); + nbTrack=0; } @@ -97,10 +117,21 @@ void Analysis::Init() { void Analysis::TreatEvent() { // Reinitiate calculated variable ReInitValue(); - double XTarget = CATS->GetPositionOnTarget().X(); - double YTarget = CATS->GetPositionOnTarget().Y(); - TVector3 BeamDirection = CATS->GetBeamDirection(); - + double XTarget, YTarget; + TVector3 BeamDirection; + if(!simulation){ + XTarget = CATS->GetPositionOnTarget().X(); + YTarget = CATS->GetPositionOnTarget().Y(); + BeamDirection = CATS->GetBeamDirection(); + } + else{ + XTarget = 0; + YTarget = 0; + BeamDirection = TVector3(0,0,1); + OriginalELab = ReactionConditions->GetKineticEnergy(0); + OriginalThetaLab = ReactionConditions->GetTheta(0); + BeamEnergy = ReactionConditions->GetBeamEnergy(); + } BeamImpact = TVector3(XTarget,YTarget,0); // determine beam energy for a randomized interaction point in target // 1% FWHM randominastion (E/100)/2.35 @@ -151,7 +182,7 @@ void Analysis::TreatEvent() { // Evaluate energy using the thickness ELab = LightAl.EvaluateInitialEnergy( Energy ,0.4*micrometer , ThetaM2Surface); // Target Correction - ELab = LightTarget.EvaluateInitialEnergy( ELab ,TargetThickness/2., ThetaNormalTarget); + ELab = LightTarget.EvaluateInitialEnergy( ELab ,TargetThickness*0.5, ThetaNormalTarget); if(LightWindow) ELab = LightWindow->EvaluateInitialEnergy( ELab ,WindowsThickness, ThetaNormalTarget); @@ -192,8 +223,10 @@ void Analysis::TreatEvent() { // Part 2 : Impact Energy Energy = ELab = 0; Energy = MG->GetEnergyDeposit(countMugast); + + // ELab = LightAl.EvaluateInitialEnergy( Energy ,0.4*micrometer , ThetaMGSurface); // Target Correction - ELab = LightTarget.EvaluateInitialEnergy( Energy ,TargetThickness*0.5, ThetaNormalTarget); + ELab = LightTarget.EvaluateInitialEnergy( Energy,TargetThickness*0.5, ThetaNormalTarget); if(LightWindow) ELab = LightWindow->EvaluateInitialEnergy( ELab ,WindowsThickness, ThetaNormalTarget); @@ -207,7 +240,7 @@ void Analysis::TreatEvent() { ThetaLab=ThetaLab/deg; }//end loop Mugast - + //////////////////////////////////////////////////////////////////////////// ///////////////////////////////// LOOP on AGATA //////////////////////////// //////////////////////////////////////////////////////////////////////////// @@ -230,7 +263,7 @@ void Analysis::TreatEvent() { GammaLV.Boost(-beta); // Get EDC EDC=GammaLV.Energy(); - } + } } @@ -249,6 +282,7 @@ void Analysis::InitOutputBranch() { RootOutput::getInstance()->GetTree()->Branch("Y",&Y,"Y/D"); RootOutput::getInstance()->GetTree()->Branch("Z",&Z,"Z/D"); RootOutput::getInstance()->GetTree()->Branch("dE",&dE,"dE/D"); + if(!simulation){ // Vamos RootOutput::getInstance()->GetTree()->Branch("LTS",<S,"LTS/l"); @@ -271,33 +305,50 @@ void Analysis::InitOutputBranch() { RootOutput::getInstance()->GetTree()->Branch("coreTS",coreTS,"coreTS[nbCores]/l"); RootOutput::getInstance()->GetTree()->Branch("coreE0",coreE0,"coreE0[nbCores]/F"); // + } + else{ + RootOutput::getInstance()->GetTree()->Branch("OriginalELab",&OriginalELab,"OriginalELab/D"); + RootOutput::getInstance()->GetTree()->Branch("OriginalThetaLab",&OriginalThetaLab,"OriginalThetaLab/D"); + RootOutput::getInstance()->GetTree()->Branch("BeamEnergy",&BeamEnergy,"BeamEnergy/D"); + } } //////////////////////////////////////////////////////////////////////////////// void Analysis::InitInputBranch(){ // RootInput:: getInstance()->GetChain()->SetBranchAddress("GATCONF",&vGATCONF); - // Vamos - RootInput::getInstance()->GetChain()->SetBranchAddress("LTS",<S); - // Agata - RootInput::getInstance()->GetChain()->SetBranchAddress("TStrack",&TStrack); - RootInput::getInstance()->GetChain()->SetBranchAddress("nbTrack",&nbTrack); - RootInput::getInstance()->GetChain()->SetBranchAddress("trackE",trackE); - RootInput::getInstance()->GetChain()->SetBranchAddress("trackX1",trackX1); - RootInput::getInstance()->GetChain()->SetBranchAddress("trackY1",trackY1); - RootInput::getInstance()->GetChain()->SetBranchAddress("trackZ1",trackZ1); - RootInput::getInstance()->GetChain()->SetBranchAddress("trackT",trackT); - RootInput::getInstance()->GetChain()->SetBranchAddress("trackCrystalID",trackCrystalID); - RootInput::getInstance()->GetChain()->SetBranchAddress("nbCores",&nbCores); - RootInput::getInstance()->GetChain()->SetBranchAddress("coreId",coreId); - RootInput::getInstance()->GetChain()->SetBranchAddress("coreTS",coreTS); - RootInput::getInstance()->GetChain()->SetBranchAddress("coreE0",coreE0); + if(!simulation){ + // Vamos + RootInput::getInstance()->GetChain()->SetBranchAddress("LTS",<S); + // Agata + RootInput::getInstance()->GetChain()->SetBranchAddress("TStrack",&TStrack); + RootInput::getInstance()->GetChain()->SetBranchAddress("nbTrack",&nbTrack); + RootInput::getInstance()->GetChain()->SetBranchAddress("trackE",trackE); + RootInput::getInstance()->GetChain()->SetBranchAddress("trackX1",trackX1); + RootInput::getInstance()->GetChain()->SetBranchAddress("trackY1",trackY1); + RootInput::getInstance()->GetChain()->SetBranchAddress("trackZ1",trackZ1); + RootInput::getInstance()->GetChain()->SetBranchAddress("trackT",trackT); + RootInput::getInstance()->GetChain()->SetBranchAddress("trackCrystalID",trackCrystalID); + RootInput::getInstance()->GetChain()->SetBranchAddress("nbCores",&nbCores); + RootInput::getInstance()->GetChain()->SetBranchAddress("coreId",coreId); + RootInput::getInstance()->GetChain()->SetBranchAddress("coreTS",coreTS); + RootInput::getInstance()->GetChain()->SetBranchAddress("coreE0",coreE0); + } + else{ + RootInput:: getInstance()->GetChain()->SetBranchStatus("InitialConditions",true ); + RootInput:: getInstance()->GetChain()->SetBranchStatus("fIC_*",true ); + RootInput:: getInstance()->GetChain()->SetBranchAddress("InitialConditions",&Initial); + RootInput:: getInstance()->GetChain()->SetBranchStatus("ReactionConditions",true ); + RootInput:: getInstance()->GetChain()->SetBranchStatus("fRC_*",true ); + RootInput:: getInstance()->GetChain()->SetBranchAddress("ReactionConditions",&ReactionConditions); + } } //////////////////////////////////////////////////////////////////////////////// void Analysis::ReInitValue(){ Ex = -1000 ; EDC= -1000; ELab = -1000; + BeamEnergy = -1000; ThetaLab = -1000; ThetaCM = -1000; X = -1000; @@ -318,13 +369,13 @@ NPL::VAnalysis* Analysis::Construct(){ // Registering the construct method to the factory // //////////////////////////////////////////////////////////////////////////////// extern "C"{ -class proxy_analysis{ - public: - proxy_analysis(){ - NPL::AnalysisFactory::getInstance()->SetConstructor(Analysis::Construct); - } -}; - -proxy_analysis p_analysis; + class proxy_analysis{ + public: + proxy_analysis(){ + NPL::AnalysisFactory::getInstance()->SetConstructor(Analysis::Construct); + } + }; + + proxy_analysis p_analysis; } diff --git a/Projects/MUGAST/Analysis.h b/Projects/MUGAST/Analysis.h index 65afe5a68a47d6a182d3eec4e2c572a06cf397d9..f7ae5c274056aa68375aafd6f9e6ff5fbb4426a9 100644 --- a/Projects/MUGAST/Analysis.h +++ b/Projects/MUGAST/Analysis.h @@ -26,6 +26,8 @@ #include"NPReaction.h" #include"RootOutput.h" #include"RootInput.h" +#include "TInitialConditions.h" +#include "TReactionConditions.h" #include "TMust2Physics.h" #include "TMugastPhysics.h" #include "TCATSPhysics.h" @@ -54,6 +56,9 @@ class Analysis: public NPL::VAnalysis{ double ELab; double ThetaLab; double ThetaCM; + double OriginalELab; + double OriginalThetaLab; + NPL::Reaction reaction; // Energy loss table: the G4Table are generated by the simulation NPL::EnergyLoss LightTarget; @@ -81,6 +86,7 @@ class Analysis: public NPL::VAnalysis{ double Si_E_M2 ; double CsI_E_M2 ; double Energy ; + double BeamEnergy; double ThetaGDSurface ; double X ; @@ -111,6 +117,8 @@ class Analysis: public NPL::VAnalysis{ TMust2Physics* M2; TMugastPhysics* MG; TCATSPhysics* CATS; - + bool simulation; + TInitialConditions* Initial; + TReactionConditions* ReactionConditions; }; #endif diff --git a/Projects/MUGAST/ShowResults.C b/Projects/MUGAST/ShowResults.C index 15bbb392d6d5d8e7e89d891a12b6c2b7c49dec2d..a11cf150ebb81c3989985b03977b5d159b9b1222 100644 --- a/Projects/MUGAST/ShowResults.C +++ b/Projects/MUGAST/ShowResults.C @@ -53,66 +53,54 @@ using namespace std; using namespace NPL; void ShowResults(){ - // get tree - TFile *f = new TFile("../../Outputs/Analysis/PhysicsTree.root"); - TTree *t = (TTree*) f->Get("PhysicsTree"); + // get tree + TFile* f = new TFile("../../Outputs/Analysis/PhysicsTree.root"); + TTree* t = (TTree*) f->Get("PhysicsTree"); - // draw kinematic information - // canvas - TCanvas *c1 = new TCanvas("c1", "kinematic information", 600, 600); - c1->Draw(); - // kinematic line - TH2F *hk = new TH2F("hk", "hk", 180, 0, 180, 200, 0, 60); - hk->GetXaxis()->SetTitle("#Theta_{lab} (deg)"); - hk->GetYaxis()->SetTitle("E_{p} (MeV)"); - cout << "counts " << t->Draw("ELab:ThetaLab>>hk","Ex>0&&Ex<6","colz") << endl; - NPL::Reaction* reaction = new NPL::Reaction(); - reaction->ReadConfigurationFile("28Mg.reaction"); - reaction->GetKinematicLine3()->Draw("c"); + // draw kinematic information + // canvas + TCanvas *c1 = new TCanvas("c1", "Results", 1000, 1000); + c1->Divide(2,2); + c1->cd(1); + // kinematic line + TH2F* hk = new TH2F("hk", "hk", 180*3, 0, 180, 1000, 0, 60); + t->Draw("ELab:ThetaLab>>hk","","col"); + hk->GetXaxis()->SetTitle("#Theta_{lab} (deg)"); + hk->GetYaxis()->SetTitle("E_{p} (MeV)"); + NPL::Reaction* reaction = new NPL::Reaction(); + reaction->ReadConfigurationFile("16Odp17O_870keV_12.reaction"); + reaction->GetKinematicLine3()->Draw("c"); - new TCanvas(); + c1->cd(2); + TH1F* hEx = new TH1F("hEx", "hEx",600, -1, 5); + t->Draw("Ex>>hEx","ThetaLab>100 && ThetaLab<156","col"); + hEx->GetXaxis()->SetTitle("Ex (MeV)"); + hEx->GetYaxis()->SetTitle("counts/10 keV"); + + c1->cd(3); TH1F *hCM = new TH1F("hCM", "hCM", 36, 0, 180); - t->Draw("ThetaCM>>hCM","Ex>0&&Ex<6","",2900); + t->Draw("ThetaCM>>hCM","Ex>0&&Ex<6",""); for(int i = 0 ; i < hCM->GetNbinsX();i++){ if(hCM->GetBinCenter(i)==37.5 || hCM->GetBinCenter(i)==97.5|| hCM->GetBinCenter(i)==167.5|| hCM->GetBinCenter(i)==42.5){ hCM->SetBinContent(i,0); - - } - - } - gPad->SetLogy(); - - TFile* file= new TFile("effMUGAST.root"); - TH1* hOmega = (TH1*)file->FindObjectAny("hDetecThetaCM"); - hOmega->Rebin(5); - hCM->Sumw2(); - hCM->Divide(hOmega); - TGraph* g= new TGraph("22.jjj"); - g->Draw("c"); - hCM->Scale(g->Eval(32.5)/hCM->GetBinContent(hCM->FindBin(32.5))); - TGraph* g2= new TGraph("22.l2"); - g2->Draw("c"); - TGraph* g3= new TGraph("22.l3"); - g3->Draw("c"); + } + } + TCanvas *c2 = new TCanvas("c2", "Control", 1000, 1000); + c2->Divide(2,2); + c2->cd(1); + TH1F* hcT = new TH1F("hcT", "hcT", 180*3, -1,1); + t->Draw("ThetaLab-OriginalThetaLab>>hcT","","col"); + TLine* lT = new TLine(0,0,180,180); + //lT->Draw(); + c2->cd(2); + TH1F* hcE = new TH1F("hcE", "hcE", 1000, -1, 1); + t->Draw("ELab-OriginalELab>>hcE","","col"); + TLine* lE = new TLine(0,0,60,60); + //lE->Draw(); + c2->cd(3); + TH1F* hcBE = new TH1F("hcBE", "hcBE", 100, 90, 100); + t->Draw("BeamEnergy>>hcBE","",""); } - -void CountingRates(Double_t ibeam = 1e5, Double_t ubt = 30){ - // load event generator file - NPL::Reaction* reaction = new NPL::Reaction(); - reaction->ReadConfigurationFile("28Mg.reaction"); -// reaction->ReadConfigurationFile("11Be_d3He.reaction"); - // get angular distribution - TH1F *dsig = reaction->GetCrossSectionHist(); - dsig->Draw(); - // calculate total cross section - Double_t stot = reaction->GetTotalCrossSection(); - cout << "total cross section = " << reaction->GetTotalCrossSection() << " mb" << endl; - - // get target thickness -// NPL::DetectorManager* myDetector = new NPL::DetectorManager(); -// myDetector->ReadConfigurationFile("MUGAST_Manu.detector"); - -} diff --git a/Projects/MUGAST/configs/ConfigMugast.dat b/Projects/MUGAST/configs/ConfigMugast.dat index 841d10d8db1acbc98a785b95142005bcc507e27c..e4c1c6fb23fd185f6eef4360c05b1dc4acf6fd45 100644 --- a/Projects/MUGAST/configs/ConfigMugast.dat +++ b/Projects/MUGAST/configs/ConfigMugast.dat @@ -1,6 +1,5 @@ ConfigMugast TAKE_E_X= 1 - %raw channel 86 corresponds to stripY 46 DISABLE_CHANNEL_Y= 3 123 MAX_STRIP_MULTIPLICITY= 100 STRIP_ENERGY_MATCHING= 1 MeV diff --git a/Projects/MUGAST/e793.detector b/Projects/MUGAST/e793.detector new file mode 100644 index 0000000000000000000000000000000000000000..6fea5b1a70e1252811c0f365df477d5e7787cf6c --- /dev/null +++ b/Projects/MUGAST/e793.detector @@ -0,0 +1,148 @@ +%%%%%%%%%%Detector%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%1 +Target + THICKNESS= 9.43 micrometer + ANGLE= 0 deg + RADIUS= 10 mm + MATERIAL= CD2 + X= 0 mm + Y= 0 mm + Z= 0 mm + NbSlices= 10 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%1 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +CATSDetector + X1_Y1= 35.56 -35.56 -2658 mm + X28_Y28= -35.56 35.56 -2658 mm + X1_Y28= 35.56 35.56 -2658 mm + X28_Y1= -35.56 -35.56 -2658 mm +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +CATSDetector + X28_Y1= -35.56 35.56 -2045 mm + X1_Y28= 35.56 -35.56 -2045 mm + X28_Y28= -35.56 -35.56 -2045 mm + X1_Y1= 35.56 35.56 -2045 mm +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%% Telescope 1 %%%%%%% +M2Telescope + X128_Y128= 115.88 9.61 154.54 mm + X128_Y1= 104.8 101.89 125.09 mm + X1_Y1= 14.55 102.4 160.63 mm + X1_Y128= 25.63 10.12 190.08 mm + SI= 1.00 + SILI= 0.00 + CSI= 1.00 + VIS= all + +%%%%%%% Telescope 2 %%%%%%% +M2Telescope + X128_Y128= -11.23 102.42 160.87 mm + X128_Y1= -101.39 102.39 124.37 mm + X1_Y1= -113.17 10.36 153.56 mm + X1_Y128= -23.03 10.38 190.05 mm + SI= 1.00 + SILI= 0.00 + CSI= 1.00 + VIS= all + +%%%%%%% Telescope 3 %%%%%%% +M2Telescope + X128_Y128= -113.28 -12.52 153.32 mm + X128_Y1= -101.58 -104.77 124.82 mm + X1_Y1= -11.39 -104.58 161.48 mm + X1_Y128= -23.1 -12.34 189.98 mm + SI= 1.00 + SILI= 0.00 + CSI= 1.00 + VIS= all + +%%%%%%% Telescope 4 %%%%%%% +M2Telescope + X128_Y128= 13.82 -104.92 160.72 mm + X128_Y1= 104.3 -104.95 125.08 mm + X1_Y1= 115.75 -12.73 153.76 mm + X1_Y128= 25.23 -12.65 189.43 mm + SI= 1.00 + SILI= 0.00 + CSI= 1.00 + VIS= all + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%POS TO UPDATE%%%%%%%%% +Mugast Trapezoid + DetectorNumber= 8 + X128_Y128= -15.11 -44.73 -99.25 mm + X1_Y128= 10.11 -44.71 -99.35 mm + X1_Y1= 43.37 -125.07 -32.74 mm + X128_Y1= -48.18 -125.07 -32.45 mm + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Mugast Trapezoid + DetectorNumber= 1 + X128_Y128= -23.05 42.83 -99.66 mm + X1_Y128= -40.74 25.21 -99.65 mm + X1_Y1= -120.65 58.67 -32.39 mm + X128_Y1= -55.66 123.17 -32.55 mm + +%%%%%%%%%%%%%%%%%%%%%POS TO UPDATE%%%%%%%%% +Mugast Trapezoid + DetectorNumber= 2 + X128_Y128= -45.68 14.28 -98.74 mm + X1_Y128= -45.68 -10.92 -98.74 mm + X1_Y1= -125.65 -44.06 -31.63 mm + X128_Y1= -125.65 47.42 -31.63 mm + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Mugast Trapezoid + DetectorNumber= 3 + X128_Y128= -48.05 -23.23 -95.05 mm + X1_Y128= -24.83 -39.35 -99.33 mm + X1_Y1= -58.24 -119.46 -32.57 mm + X128_Y1= -122.86 -54.55 -32.41 mm + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Mugast Trapezoid + DetectorNumber= 4 + X128_Y128= -15.11 -44.73 -99.25 mm + X1_Y128= 10.11 -44.71 -99.35 mm + X1_Y1= 43.37 -125.07 -32.74 mm + X128_Y1= -48.18 -125.07 -32.45 mm + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Mugast Trapezoid + DetectorNumber= 5 + X128_Y128= 21.68 -41.48 -100.19 mm + X1_Y128= 39.55 -23.81 -100.11 mm + X1_Y1= 119.55 -57.08 -33.23 mm + X128_Y1= 54.81 -121.7 -33.12 mm + +%%%%%%%%%%%%%%%%%%%%POS TO UPDATE%%%%%%%%% +%Mugast Trapezoid +% DetectorNumber= 6 +% X128_Y128= 45.68 -14.28 -98.74 mm +% X1_Y128= 45.68 10.92 -98.74 mm +% X1_Y1= 125.65 44.06 -31.63 mm +% X128_Y1= 125.65 -47.42 -31.63 mm + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Mugast Trapezoid + DetectorNumber= 7 + X128_Y128= 40.99 21.69 -98.21 mm + X1_Y128= 23.34 39.63 -98.04 mm + X1_Y1= 57.53 120.53 -32.58 mm + X128_Y1= 122.2 55.73 -32.67 mm + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Mugast Square + DetectorNumber= 9 + X128_Y128= 107.49 -95.88 0.0 mm + X1_Y128= 143.81 -8.21 0.0 mm + X1_Y1= 143.81 -8.21 91.7 mm + X128_Y1= 107.49 -95.88 91.7 mm + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Mugast Annular + DetectorNumber= 11 + Center= -0.3 1 -126.9 mm + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/Projects/MUGAST/run.mac b/Projects/MUGAST/run.mac new file mode 100644 index 0000000000000000000000000000000000000000..02b80e5efd512013cc3fcf9bb00160a53811fec6 --- /dev/null +++ b/Projects/MUGAST/run.mac @@ -0,0 +1,3 @@ +/run/beamOn 10000 +/gen/open 16Odp17O_gs.reaction +/run/beamOn 10000 diff --git a/Projects/Nebula/Nebula.detector b/Projects/Nebula/Nebula.detector index 7bb9d72bebbcf9119852278c3f165f90b8dccc9c..f46956bad3bbd1b714a32e96375dd4899d4f2258 100644 --- a/Projects/Nebula/Nebula.detector +++ b/Projects/Nebula/Nebula.detector @@ -20,4 +20,18 @@ Nebula Veto= 0 Frame= 0 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Nebula + POS= 0 0 10 m + NumberOfModule= 30 + Veto= 1 + Frame= 1 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Nebula + POS= 0 0 10.15 m + NumberOfModule= 30 + Veto= 0 + Frame= 0 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + diff --git a/Projects/Strasse/Analysis.cxx b/Projects/Strasse/Analysis.cxx new file mode 100644 index 0000000000000000000000000000000000000000..1f5acb9334ba72a1ba566747be1d52f91137d070 --- /dev/null +++ b/Projects/Strasse/Analysis.cxx @@ -0,0 +1,238 @@ +/***************************************************************************** + * Copyright (C) 2009-2014 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 : july 2020 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * Class describing the property of an Analysis object * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + * * + *****************************************************************************/ +#include<iostream> +using namespace std; +#include"Analysis.h" +#include"NPAnalysisFactory.h" +#include"NPDetectorManager.h" +#include"NPOptionManager.h" +#include"NPFunction.h" +#include"NPTrackingUtility.h" +#include"NPPhysicalConstants.h" +//////////////////////////////////////////////////////////////////////////////// +Analysis::Analysis(){ +} +//////////////////////////////////////////////////////////////////////////////// +Analysis::~Analysis(){ +} + +//////////////////////////////////////////////////////////////////////////////// +void Analysis::Init(){ + IC= new TInitialConditions; + DC= new TInteractionCoordinates; + RC= new TReactionConditions; + + InitOutputBranch(); + InitInputBranch(); + + Strasse = (TStrassePhysics*) m_DetectorManager -> GetDetector("Strasse"); + Catana = (TCatanaPhysics*) m_DetectorManager -> GetDetector("Catana"); + // reaction properties + m_QFS = new NPL::QFS(); + m_QFS->ReadConfigurationFile(NPOptionManager::getInstance()->GetReactionFile()); + // reaction properties + myBeam = new NPL::Beam(); + myBeam->ReadConfigurationFile(NPOptionManager::getInstance()->GetReactionFile()); + InitialBeamEnergy = myBeam->GetEnergy()/* * myBeam->GetA()*/; + // target thickness + TargetThickness = m_DetectorManager->GetTargetThickness(); + string TargetMaterial = m_DetectorManager->GetTargetMaterial(); + // EnergyLoss Tables + string BeamName = NPL::ChangeNameToG4Standard(myBeam->GetName()); + BeamTarget = NPL::EnergyLoss(BeamName+"_"+TargetMaterial+".G4table","G4Table",100); + protonTarget = NPL::EnergyLoss("proton_"+TargetMaterial+".G4table","G4Table",100); + protonAl = NPL::EnergyLoss("proton_Al.G4table","G4Table",100); + protonSi = NPL::EnergyLoss("proton_Si.G4table","G4Table",100); + LV_T.SetVectM(TVector3(0,0,0),NPUNITS::proton_mass_c2); +} + +//////////////////////////////////////////////////////////////////////////////// +void Analysis::TreatEvent(){ + // Reinitiate calculated variable + ReInitValue(); + unsigned int size = Strasse->GetEventMultiplicity(); + if(size==2){ // 2 proton detected + // Proton 1 + TVector3 InnerPos1 = Strasse->GetInnerPositionOfInteraction(0); + TVector3 OuterPos1 = Strasse->GetOuterPositionOfInteraction(0); + TVector3 Proton1 = OuterPos1-InnerPos1; + // Proton 2 + TVector3 InnerPos2 = Strasse->GetInnerPositionOfInteraction(1); + TVector3 OuterPos2 = Strasse->GetOuterPositionOfInteraction(1); + TVector3 Proton2 = OuterPos2-InnerPos2; + + deltaPhi = abs(Proton1.Phi()/deg-Proton2.Phi()/deg); + sumTheta = Proton1.Theta()/deg+Proton2.Theta()/deg; + Theta12 = Proton1.Angle(Proton2)/deg; + + // reject event that make no physical sense + /*if(deltaPhi<170 && sumTheta<80){ + return; + } + */ + // computing minimum distance of the two lines + TVector3 Vertex; + TVector3 delta; + Distance = NPL::MinimumDistanceTwoLines(InnerPos1,OuterPos1,InnerPos2,OuterPos2,Vertex,delta); + VertexX=Vertex.X(); + VertexY=Vertex.Y(); + VertexZ=Vertex.Z(); + deltaX=delta.X(); + deltaY=delta.Y(); + deltaZ=delta.Z(); + + // Look for associated Catana event + double d1,d2; + unsigned int i1,i2; + i1 = Catana->FindClosestHitToLine(InnerPos1,OuterPos1,d1); + i2 = Catana->FindClosestHitToLine(InnerPos2,OuterPos2,d2); + if(i1!=i2){ + E1 = ReconstructProtonEnergy(Vertex,Proton1,Catana->Energy[i1]); + E2 = ReconstructProtonEnergy(Vertex,Proton2,Catana->Energy[i2]); + double TA = BeamTarget.Slow(InitialBeamEnergy,abs(VertexZ-75),0); + // setting up Lorentz Vector from measured trajectories and energies + TVector3 PA(0,0,sqrt(TA*(TA+2*m_QFS->GetNucleusA()->Mass()))); // for like there is no BDC + Proton1=E1*Proton1.Unit(); + Proton2=E2*Proton2.Unit(); + + LV_A.SetVectM(PA,m_QFS->GetNucleusA()->Mass()); + double P1= sqrt(E1*(E1+2*NPUNITS::proton_mass_c2)); + double P2= sqrt(E2*(E2+2*NPUNITS::proton_mass_c2)); + + LV_p1.SetVectM(Proton1.Unit()*P1,NPUNITS::proton_mass_c2); + LV_p2.SetVectM(Proton2.Unit()*P2,NPUNITS::proton_mass_c2); + + // computing Ex from Missing Mass + LV_B = LV_A + LV_T - LV_p1 - LV_p2; + //LV_B = RC->GetParticleMomentum(2); + Ex = LV_B.M() - m_QFS->GetNucleusB()->Mass(); + } + + } +} + +//////////////////////////////////////////////////////////////////////////////// +double Analysis::ReconstructProtonEnergy(const TVector3& x0, const TVector3& dir,const double& Ecatana){ + TVector3 Normal = TVector3(0,0,1); + Normal.SetPhi(dir.Phi()); + double Theta = dir.Angle(Normal); + // Catana Al housing + double E = protonAl.EvaluateInitialEnergy(Ecatana,0.5*mm,Theta); + // Strasse Chamber + E = protonAl.EvaluateInitialEnergy(E,3*mm,Theta); + // Outer Barrel + E = protonSi.EvaluateInitialEnergy(E,300*micrometer,Theta); + // Inner Barrel + E = protonSi.EvaluateInitialEnergy(E,200*micrometer,Theta); + // LH2 target + static TVector3 x1; + x1= x0+dir; + TVector3 T1(0,30,0); + TVector3 T2(0,30,1); + T1.SetPhi(dir.Phi()); + T2.SetPhi(dir.Phi()); + TVector3 Vertex,delta; + double d = NPL::MinimumDistanceTwoLines(x0,x1,T1,T2,Vertex,delta); + E = protonTarget.EvaluateInitialEnergy(E,d,Theta); + } + + +//////////////////////////////////////////////////////////////////////////////// +TVector3 Analysis::InterpolateInPlaneZ(TVector3 V0, TVector3 V1, double Zproj){ + TVector3 Vproj(-999,-999,-999); + double t = (Zproj - V1.Z()) / (V1.Z()-V0.Z()); + double Xproj= V1.X() + (V1.X()-V0.X()) * t; + double Yproj= V1.Y() + (V1.Y()-V0.Y()) * t; + Vproj.SetXYZ(Xproj,Yproj,Zproj); + return Vproj; +} + +//////////////////////////////////////////////////////////////////////////////// +void Analysis::End(){ +} +//////////////////////////////////////////////////////////////////////////////// +void Analysis::InitOutputBranch() { + RootOutput::getInstance()->GetTree()->Branch("Ex",&Ex,"Ex/D"); + RootOutput::getInstance()->GetTree()->Branch("E1",&E1,"E1/D"); + RootOutput::getInstance()->GetTree()->Branch("E2",&E2,"E2/D"); + RootOutput::getInstance()->GetTree()->Branch("Theta12",&Theta12,"Theta12/D"); + RootOutput::getInstance()->GetTree()->Branch("ThetaCM",&ThetaCM,"ThetaCM/D"); + RootOutput::getInstance()->GetTree()->Branch("VertexX",&VertexX,"VertexX/D"); + RootOutput::getInstance()->GetTree()->Branch("VertexY",&VertexY,"VertexY/D"); + RootOutput::getInstance()->GetTree()->Branch("VertexZ",&VertexZ,"VertexZ/D"); + RootOutput::getInstance()->GetTree()->Branch("deltaX",&deltaX,"deltaX/D"); + RootOutput::getInstance()->GetTree()->Branch("deltaY",&deltaY,"deltaY/D"); + RootOutput::getInstance()->GetTree()->Branch("deltaZ",&deltaZ,"deltaZ/D"); + RootOutput::getInstance()->GetTree()->Branch("deltaPhi",&deltaPhi,"deltaPhi/D"); + RootOutput::getInstance()->GetTree()->Branch("sumTheta",&sumTheta,"sumTheta/D"); + + + RootOutput::getInstance()->GetTree()->Branch("Distance",&Distance,"Distance/D"); + RootOutput::getInstance()->GetTree()->Branch("InteractionCoordinates","TInteractionCoordinates",&DC); + RootOutput::getInstance()->GetTree()->Branch("ReactionConditions","TReactionConditions",&RC); +} + +//////////////////////////////////////////////////////////////////////////////// +void Analysis::InitInputBranch(){ + RootInput:: getInstance()->GetChain()->SetBranchAddress("InteractionCoordinates",&DC); + RootInput:: getInstance()->GetChain()->SetBranchAddress("ReactionConditions",&RC); +} +//////////////////////////////////////////////////////////////////////////////// +void Analysis::ReInitValue(){ + Ex = -1000 ; + E1= -1000; + E2 = -1000; + Theta12 = -1000; + ThetaCM = -1000; + VertexX=-1000; + VertexY=-1000; + VertexZ=-1000; + deltaX=-1000; + deltaY=-1000; + deltaZ=-1000; + Distance=-1000; + sumTheta=-1000; + deltaPhi=-1000; +} + + +//////////////////////////////////////////////////////////////////////////////// +// Construct Method to be pass to the AnalysisFactory // +//////////////////////////////////////////////////////////////////////////////// +NPL::VAnalysis* Analysis::Construct(){ + return (NPL::VAnalysis*) new Analysis(); +} + +//////////////////////////////////////////////////////////////////////////////// +// Registering the construct method to the factory // +//////////////////////////////////////////////////////////////////////////////// +extern "C"{ +class proxy{ + public: + proxy(){ + NPL::AnalysisFactory::getInstance()->SetConstructor(Analysis::Construct); + } +}; + +proxy p; +} + diff --git a/Projects/Strasse/Analysis.h b/Projects/Strasse/Analysis.h new file mode 100644 index 0000000000000000000000000000000000000000..52cf9bea4179e94f01bed38651b95a03739a7a32 --- /dev/null +++ b/Projects/Strasse/Analysis.h @@ -0,0 +1,97 @@ +#ifndef Analysis_h +#define Analysis_h +/***************************************************************************** + * Copyright (C) 2009-2014 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 : march 2025 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * Class describing the property of an Analysis object * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + * * + *****************************************************************************/ +#include"NPVAnalysis.h" +#include"NPEnergyLoss.h" +#include"NPQFS.h" +#include"RootOutput.h" +#include"RootInput.h" +#include "TStrassePhysics.h" +#include "TCatanaPhysics.h" +#include "TInitialConditions.h" +#include "TInteractionCoordinates.h" +#include "TReactionConditions.h" +#include <TRandom3.h> +#include <TVector3.h> +#include <TLorentzVector.h> +#include <TMath.h> + +class Analysis: public NPL::VAnalysis{ + public: + Analysis(); + ~Analysis(); + + public: + void Init(); + void TreatEvent(); + void End(); + void InitOutputBranch(); + void InitInputBranch(); + void ReInitValue(); + static NPL::VAnalysis* Construct(); + TVector3 InterpolateInPlaneZ(TVector3,TVector3,double); + + private: + double Ex; + double E1; + double E2; + double Theta12; + double ThetaCM; + double VertexX; + double VertexY; + double VertexZ; + double deltaX; + double deltaY; + double deltaZ; + double Distance; + double deltaPhi; + double sumTheta; + TLorentzVector LV_A; + TLorentzVector LV_T; + TLorentzVector LV_B; + TLorentzVector LV_p1; + TLorentzVector LV_p2; + + NPL::Beam* myBeam; + NPL::QFS* m_QFS; + // Energy loss table: the G4Table are generated by the simulation + EnergyLoss BeamTarget; + EnergyLoss protonTarget; + EnergyLoss protonAl; + EnergyLoss protonSi; + double ReconstructProtonEnergy(const TVector3& x0,const TVector3& dir,const double& Ecatana); + + TVector3 BeamImpact; + + double TargetThickness ; + // Beam Energy + double InitialBeamEnergy ; // TKE beam in MeV + // intermediate variable + TRandom3 Rand ; + TStrassePhysics* Strasse; + TCatanaPhysics* Catana; + TInitialConditions* IC ; + TInteractionCoordinates* DC; + TReactionConditions* RC; +}; +#endif diff --git a/Projects/Strasse/CMakeLists.txt b/Projects/Strasse/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..22c74affdfc45019bdda2594f8439c52d4ab97ec --- /dev/null +++ b/Projects/Strasse/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required (VERSION 2.8) +# Setting the policy to match Cmake version +cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}) +# include the default NPAnalysis cmake file +include("../../NPLib/ressources/CMake/NPAnalysis.cmake") diff --git a/Projects/Strasse/PhysicsListOption.txt b/Projects/Strasse/PhysicsListOption.txt new file mode 100644 index 0000000000000000000000000000000000000000..ff38d11c7d6361c44a8d00159a7a5543a22c25cd --- /dev/null +++ b/Projects/Strasse/PhysicsListOption.txt @@ -0,0 +1,11 @@ +EmPhysicsList Option4 +DefaultCutOff 1000000 +IonBinaryCascadePhysics 0 +NPIonInelasticPhysics 0 +EmExtraPhysics 0 +HadronElasticPhysics 0 +StoppingPhysics 0 +OpticalPhysics 0 +HadronPhysicsINCLXX 0 +HadronPhysicsQGSP_BIC_HP 0 +Decay 1 diff --git a/Projects/Strasse/geometry/Catana.csv b/Projects/Strasse/geometry/Catana.csv new file mode 100755 index 0000000000000000000000000000000000000000..10ec03097802f1fc4cf59eeb02c9da302b88c180 --- /dev/null +++ b/Projects/Strasse/geometry/Catana.csv @@ -0,0 +1,141 @@ +ID,DetectorType,Layer,X,Y,Z,Theta,Phi +1, 1, 1, -38.4258, 242.611, 26.5, 84.75, 9 +2, 1, 1, -111.516, 218.862, 26.5, 84.75, 27 +3, 1, 1, -173.69, 173.69, 26.5, 84.75, 45 +4, 1, 1, -218.862, 111.516, 26.5, 84.75, 63 +5, 1, 1, -242.611, 38.4258, 26.5, 84.75, 81 +6, 1, 1, -242.611, -38.4258, 26.5, 84.75, 99 +7, 1, 1, -218.862, -111.516, 26.5, 84.75, 117 +8, 1, 1, -173.69, -173.69, 26.5, 84.75, 135 +9, 1, 1, -111.516, -218.862, 26.5, 84.75, 153 +10, 1, 1, -38.4258, -242.611, 26.5, 84.75, 171 +11, 1, 1, 38.4258, -242.611, 26.5, 84.75, 189 +12, 1, 1, 111.516, -218.862, 26.5, 84.75, 207 +13, 1, 1, 173.69, -173.69, 26.5, 84.75, 225 +14, 1, 1, 218.862, -111.516, 26.5, 84.75, 243 +15, 1, 1, 242.611, -38.4258, 26.5, 84.75, 261 +16, 1, 1, 242.611, 38.4258, 26.5, 84.75, 279 +17, 1, 1, 218.862, 111.516, 26.5, 84.75, 297 +18, 1, 1, 173.69, 173.69, 26.5, 84.75, 315 +19, 1, 1, 111.516, 218.862, 26.5, 84.75, 333 +20, 1, 1, 38.4258, 242.611, 26.5, 84.75, 351 +21, 1, 2, -39.4863, 249.307, 74.7271, 74.25, 9 +22, 1, 2, -114.594, 224.903, 74.7271, 74.25, 27 +23, 1, 2, -178.484, 178.484, 74.7271, 74.25, 45 +24, 1, 2, -224.903, 114.594, 74.7271, 74.25, 63 +25, 1, 2, -249.307, 39.4863, 74.7271, 74.25, 81 +26, 1, 2, -249.307, -39.4863, 74.7271, 74.25, 99 +27, 1, 2, -224.903, -114.594, 74.7271, 74.25, 117 +28, 1, 2, -178.484, -178.484, 74.7271, 74.25, 135 +29, 1, 2, -114.594, -224.903, 74.7271, 74.25, 153 +30, 1, 2, -39.4863, -249.307, 74.7271, 74.25, 171 +31, 1, 2, 39.4863, -249.307, 74.7271, 74.25, 189 +32, 1, 2, 114.594, -224.903, 74.7271, 74.25, 207 +33, 1, 2, 178.484, -178.484, 74.7271, 74.25, 225 +34, 1, 2, 224.903, -114.594, 74.7271, 74.25, 243 +35, 1, 2, 249.307, -39.4863, 74.7271, 74.25, 261 +36, 1, 2, 249.307, 39.4863, 74.7271, 74.25, 279 +37, 1, 2, 224.903, 114.594, 74.7271, 74.25, 297 +38, 1, 2, 178.484, 178.484, 74.7271, 74.25, 315 +39, 1, 2, 114.594, 224.903, 74.7271, 74.25, 333 +40, 1, 2, 39.4863, 249.307, 74.7271, 74.25, 351 +41, 2, 3, -39.34, 248.383, 123.2, 64, 9 +42, 2, 3, -114.169, 224.069, 123.2, 64, 27 +43, 2, 3, -177.823, 177.823, 123.2, 64, 45 +44, 2, 3, -224.069, 114.169, 123.2, 64, 63 +45, 2, 3, -248.383, 39.34, 123.2, 64, 81 +46, 2, 3, -248.383, -39.34, 123.2, 64, 99 +47, 2, 3, -224.069, -114.169, 123.2, 64, 117 +48, 2, 3, -177.823, -177.823, 123.2, 64, 135 +49, 2, 3, -114.169, -224.069, 123.2, 64, 153 +50, 2, 3, -39.34, -248.383, 123.2, 64, 171 +51, 2, 3, 39.34, -248.383, 123.2, 64, 189 +52, 2, 3, 114.169, -224.069, 123.2, 64, 207 +53, 2, 3, 177.823, -177.823, 123.2, 64, 225 +54, 2, 3, 224.069, -114.169, 123.2, 64, 243 +55, 2, 3, 248.383, -39.34, 123.2, 64, 261 +56, 2, 3, 248.383, 39.34, 123.2, 64, 279 +57, 2, 3, 224.069, 114.169, 123.2, 64, 297 +58, 2, 3, 177.823, 177.823, 123.2, 64, 315 +59, 2, 3, 114.169, 224.069, 123.2, 64, 333 +60, 2, 3, 39.34, 248.383, 123.2, 64, 351 +61, 2, 4, -37.4072, 236.18, 168.2, 54, 9 +62, 2, 4, -108.56, 213.061, 168.2, 54, 27 +63, 2, 4, -169.086, 169.086, 168.2, 54, 45 +64, 2, 4, -213.061, 108.56, 168.2, 54, 63 +65, 2, 4, -236.18, 37.4072, 168.2, 54, 81 +66, 2, 4, -236.18, -37.4072, 168.2, 54, 99 +67, 2, 4, -213.061, -108.56, 168.2, 54, 117 +68, 2, 4, -169.086, -169.086, 168.2, 54, 135 +69, 2, 4, -108.56, -213.061, 168.2, 54, 153 +70, 2, 4, -37.4072, -236.18, 168.2, 54, 171 +71, 2, 4, 37.4072, -236.18, 168.2, 54, 189 +72, 2, 4, 108.56, -213.061, 168.2, 54, 207 +73, 2, 4, 169.086, -169.086, 168.2, 54, 225 +74, 2, 4, 213.061, -108.56, 168.2, 54, 243 +75, 2, 4, 236.18, -37.4072, 168.2, 54, 261 +76, 2, 4, 236.18, 37.4072, 168.2, 54, 279 +77, 2, 4, 213.061, 108.56, 168.2, 54, 297 +78, 2, 4, 169.086, 169.086, 168.2, 54, 315 +79, 2, 4, 108.56, 213.061, 168.2, 54, 333 +80, 2, 4, 37.4072, 236.18, 168.2, 54, 351 +81, 3, 5, -33.7152, 212.87, 211.3, 43.5, 9 +82, 3, 5, -97.8454, 192.032, 211.3, 43.5, 27 +83, 3, 5, -152.398, 152.398, 211.3, 43.5, 45 +84, 3, 5, -192.032, 97.8454, 211.3, 43.5, 63 +85, 3, 5, -212.87, 33.7152, 211.3, 43.5, 81 +86, 3, 5, -212.87, -33.7152, 211.3, 43.5, 99 +87, 3, 5, -192.032, -97.8454, 211.3, 43.5, 117 +88, 3, 5, -152.398, -152.398, 211.3, 43.5, 135 +89, 3, 5, -97.8454, -192.032, 211.3, 43.5, 153 +90, 3, 5, -33.7152, -212.87, 211.3, 43.5, 171 +91, 3, 5, 33.7152, -212.87, 211.3, 43.5, 189 +92, 3, 5, 97.8454, -192.032, 211.3, 43.5, 207 +93, 3, 5, 152.398, -152.398, 211.3, 43.5, 225 +94, 3, 5, 192.032, -97.8454, 211.3, 43.5, 243 +95, 3, 5, 212.87, -33.7152, 211.3, 43.5, 261 +96, 3, 5, 212.87, 33.7152, 211.3, 43.5, 279 +97, 3, 5, 192.032, 97.8454, 211.3, 43.5, 297 +98, 3, 5, 152.398, 152.398, 211.3, 43.5, 315 +99, 3, 5, 97.8454, 192.032, 211.3, 43.5, 333 +100, 3, 5, 33.7152, 212.87, 211.3, 43.5, 351 +101, 4, 6, -28.1811, 177.929, 250.169, 32.5, 9 +102, 4, 6, -81.7848, 160.512, 250.169, 32.5, 27 +103, 4, 6, -127.383, 127.383, 250.169, 32.5, 45 +104, 4, 6, -160.512, 81.7848, 250.169, 32.5, 63 +105, 4, 6, -177.929, 28.1811, 250.169, 32.5, 81 +106, 4, 6, -177.929, -28.1811, 250.169, 32.5, 99 +107, 4, 6, -160.512, -81.7848, 250.169, 32.5, 117 +108, 4, 6, -127.383, -127.383, 250.169, 32.5, 135 +109, 4, 6, -81.7848, -160.512, 250.169, 32.5, 153 +110, 4, 6, -28.1811, -177.929, 250.169, 32.5, 171 +111, 4, 6, 28.1811, -177.929, 250.169, 32.5, 189 +112, 4, 6, 81.7848, -160.512, 250.169, 32.5, 207 +113, 4, 6, 127.383, -127.383, 250.169, 32.5, 225 +114, 4, 6, 160.512, -81.7848, 250.169, 32.5, 243 +115, 4, 6, 177.929, -28.1811, 250.169, 32.5, 261 +116, 4, 6, 177.929, 28.1811, 250.169, 32.5, 279 +117, 4, 6, 160.512, 81.7848, 250.169, 32.5, 297 +118, 4, 6, 127.383, 127.383, 250.169, 32.5, 315 +119, 4, 6, 81.7848, 160.512, 250.169, 32.5, 333 +120, 4, 6, 28.1811, 177.929, 250.169, 32.5, 351 +121, 5, 7, -21.1337, 133.433, 278.822, 21.5, 9 +122, 5, 7, -61.3324, 120.372, 278.822, 21.5, 27 +123, 5, 7, -95.5275, 95.5275, 278.822, 21.5, 45 +124, 5, 7, -120.372, 61.3324, 278.822, 21.5, 63 +125, 5, 7, -133.433, 21.1337, 278.822, 21.5, 81 +126, 5, 7, -133.433, -21.1337, 278.822, 21.5, 99 +127, 5, 7, -120.372, -61.3324, 278.822, 21.5, 117 +128, 5, 7, -95.5275, -95.5275, 278.822, 21.5, 135 +129, 5, 7, -61.3324, -120.372, 278.822, 21.5, 153 +130, 5, 7, -21.1337, -133.433, 278.822, 21.5, 171 +131, 5, 7, 21.1337, -133.433, 278.822, 21.5, 189 +132, 5, 7, 61.3324, -120.372, 278.822, 21.5, 207 +133, 5, 7, 95.5275, -95.5275, 278.822, 21.5, 225 +134, 5, 7, 120.372, -61.3324, 278.822, 21.5, 243 +135, 5, 7, 133.433, -21.1337, 278.822, 21.5, 261 +136, 5, 7, 133.433, 21.1337, 278.822, 21.5, 279 +137, 5, 7, 120.372, 61.3324, 278.822, 21.5, 297 +138, 5, 7, 95.5275, 95.5275, 278.822, 21.5, 315 +139, 5, 7, 61.3324, 120.372, 278.822, 21.5, 333 +140, 5, 7, 21.1337, 133.433, 278.822, 21.5, 351 diff --git a/Projects/Strasse/geometry/strasse_edgefree.detector b/Projects/Strasse/geometry/strasse_edgefree.detector new file mode 100644 index 0000000000000000000000000000000000000000..6bc3878ee9f54d5f4fbe82a0b43b652356f9663e --- /dev/null +++ b/Projects/Strasse/geometry/strasse_edgefree.detector @@ -0,0 +1,92 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Target + THICKNESS= 150 mm + ANGLE= 0 deg + RADIUS= 15 mm + MATERIAL= LH2 + X= 0 mm + Y= 0 mm + Z= 0 mm + NbSlices= 10 + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%1 +Strasse Info + Inner_Wafer_Length= 127 mm + Inner_Wafer_Width= 34.5 mm + Inner_Wafer_Thickness= 200 micrometer + Inner_Wafer_AlThickness= 0.4 micrometer + Inner_Wafer_PADExternal= 0 mm + Inner_Wafer_PADInternal= 0 mm + Inner_Wafer_GuardRing= 0 mm + Inner_Wafer_TransverseStrips= 620 + Inner_Wafer_LongitudinalStrips= 150 + Inner_PCB_PortWidth= 0.001 mm + Inner_PCB_StarboardWidth= 0.001 mm + Inner_PCB_BevelAngle= 90 deg + Inner_PCB_UpstreamWidth= 1 mm + Inner_PCB_DownstreamWidth= 1 mm + Inner_PCB_MidWidth= 1 mm + Inner_PCB_Thickness= 0.2 mm + Outer_Wafer_Length= 124 mm + Outer_Wafer_Width= 70 mm + Outer_Wafer_Thickness= 300 micrometer + Outer_Wafer_AlThickness= 0.4 micrometer + Outer_Wafer_PADExternal= 0 mm + Outer_Wafer_PADInternal= 0 mm + Outer_Wafer_GuardRing= 0 mm + Outer_PCB_PortWidth= 0.001 mm + Outer_PCB_StarboardWidth= 0.001 mm + Outer_PCB_BevelAngle= 90 deg + Outer_PCB_UpstreamWidth= 1 mm + Outer_PCB_DownstreamWidth= 1 mm + Outer_PCB_MidWidth= 1 mm + Outer_PCB_Thickness= 0.3 mm + Outer_Wafer_TransverseStrips= 605 + Outer_Wafer_LongitudinalStrips= 325 + % all radius are external, internal deduced from thickness + Chamber_Thickness= 3 mm + Chamber_Cylinder_Length= 360 mm + Chamber_Radius= 180 mm + Chamber_ExitTube_Radius= 79.5 mm + Chamber_ExitTube_Length= 100 mm + Chamber_Flange_Inner_Radius= 50 mm + Chamber_Sphere_Radius= 220 mm + Chamber_Sphere_Shift= 60 mm + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Alias InnerPhi + Action= Copy + Value= 0 60 120 180 240 300 + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Strasse Inner + Radius= 27 mm + Z= 67.5 mm + Phi= @InnerPhi deg + Shift= 3 mm + Ref= 0 0 0 mm + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Alias OuterPhi + Action= Copy + Value= 5 65 125 185 245 305 + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Strasse Outer + Radius= 61 mm + Z= 79.5 mm + Phi= @OuterPhi deg + Shift= 0 mm + Ref= 0 0 0 mm + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%1 +Strasse Chamber + Z= -30 mm + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Catana CSV + Path= geometry/Catana.csv + Pos= 0 0 100 mm + Rshift= 100 micrometer + + diff --git a/Projects/Strasse/geometry/strasse_optimized.detector b/Projects/Strasse/geometry/strasse_optimized.detector new file mode 100644 index 0000000000000000000000000000000000000000..25d406002960ee1eb443f6765b7211af03da5ee9 --- /dev/null +++ b/Projects/Strasse/geometry/strasse_optimized.detector @@ -0,0 +1,92 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Target + THICKNESS= 150 mm + ANGLE= 0 deg + RADIUS= 15 mm + MATERIAL= LH2 + X= 0 mm + Y= 0 mm + Z= 0 mm + NbSlices= 10 + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%1 +Strasse Info + Inner_Wafer_Length= 127 mm + Inner_Wafer_Width= 33 mm + Inner_Wafer_Thickness= 200 micrometer + Inner_Wafer_AlThickness= 0.4 micrometer + Inner_Wafer_PADExternal= 0 mm + Inner_Wafer_PADInternal= 0 mm + Inner_Wafer_GuardRing= 1.5 mm + Inner_Wafer_TransverseStrips= 620 + Inner_Wafer_LongitudinalStrips= 150 + Inner_PCB_PortWidth= 1 mm + Inner_PCB_StarboardWidth= 1 mm + Inner_PCB_BevelAngle= 90 deg + Inner_PCB_UpstreamWidth= 1 mm + Inner_PCB_DownstreamWidth= 1 mm + Inner_PCB_MidWidth= 1 mm + Inner_PCB_Thickness= 1.6 mm + Outer_Wafer_Length= 124 mm + Outer_Wafer_Width= 68 mm + Outer_Wafer_Thickness= 300 micrometer + Outer_Wafer_AlThickness= 0.4 micrometer + Outer_Wafer_PADExternal= 0 mm + Outer_Wafer_PADInternal= 0 mm + Outer_Wafer_GuardRing= 1.5 mm + Outer_PCB_PortWidth= 1 mm + Outer_PCB_StarboardWidth= 1 mm + Outer_PCB_BevelAngle= 45 deg + Outer_PCB_UpstreamWidth= 1 mm + Outer_PCB_DownstreamWidth= 1 mm + Outer_PCB_MidWidth= 1 mm + Outer_PCB_Thickness= 1.6 mm + Outer_Wafer_TransverseStrips= 605 + Outer_Wafer_LongitudinalStrips= 325 + % all radius are external, internal deduced from thickness + Chamber_Thickness= 3 mm + Chamber_Cylinder_Length= 360 mm + Chamber_Radius= 180 mm + Chamber_ExitTube_Radius= 79.5 mm + Chamber_ExitTube_Length= 100 mm + Chamber_Flange_Inner_Radius= 50 mm + Chamber_Sphere_Radius= 220 mm + Chamber_Sphere_Shift= 60 mm + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Alias InnerPhi + Action= Copy + Value= 0 60 120 180 240 300 + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Strasse Inner + Radius= 27 mm + Z= 66.0 mm + Phi= @InnerPhi deg + Shift= 3 mm + Ref= 0 0 0 mm + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Alias OuterPhi + Action= Copy + Value= 5 65 125 185 245 305 + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Strasse Outer + Radius= 61 mm + Z= 78.0 mm + Phi= @OuterPhi deg + Shift= 0 mm + Ref= 0 0 0 mm + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%1 +Strasse Chamber + Z= -30 mm + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Catana CSV + Path= geometry/Catana.csv + Pos= 0 0 100 mm + Rshift= 100 micrometer + + diff --git a/Projects/Strasse/geometry/strasse_ref.detector b/Projects/Strasse/geometry/strasse_ref.detector new file mode 100644 index 0000000000000000000000000000000000000000..c542cea82b01d10d2d9cb363efe2cbae423ed81a --- /dev/null +++ b/Projects/Strasse/geometry/strasse_ref.detector @@ -0,0 +1,89 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Target + THICKNESS= 150 mm + ANGLE= 0 deg + RADIUS= 15 mm + MATERIAL= LH2 + X= 0 mm + Y= 0 mm + Z= 0 mm + NbSlices= 10 + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%1 +Strasse Info + Inner_Wafer_Length= 127 mm + Inner_Wafer_Width= 33 mm + Inner_Wafer_Thickness= 200 micrometer + Inner_Wafer_AlThickness= 0.4 micrometer + Inner_Wafer_PADExternal= 0 mm + Inner_Wafer_PADInternal= 0 mm + Inner_Wafer_GuardRing= 1.5 mm + Inner_Wafer_TransverseStrips= 620 + Inner_Wafer_LongitudinalStrips= 150 + Inner_PCB_PortWidth= 1 mm + Inner_PCB_StarboardWidth= 1 mm + Inner_PCB_BevelAngle= 45 deg + Inner_PCB_UpstreamWidth= 1 mm + Inner_PCB_DownstreamWidth= 1 mm + Inner_PCB_MidWidth= 1 mm + Inner_PCB_Thickness= 1.6 mm + Outer_Wafer_Length= 124 mm + Outer_Wafer_Width= 68 mm + Outer_Wafer_Thickness= 300 micrometer + Outer_Wafer_AlThickness= 0.4 micrometer + Outer_Wafer_PADExternal= 0 mm + Outer_Wafer_PADInternal= 0 mm + Outer_Wafer_GuardRing= 1.5 mm + Outer_PCB_PortWidth= 1 mm + Outer_PCB_StarboardWidth= 1 mm + Outer_PCB_BevelAngle= 45 deg + Outer_PCB_UpstreamWidth= 1 mm + Outer_PCB_DownstreamWidth= 1 mm + Outer_PCB_MidWidth= 1 mm + Outer_PCB_Thickness= 1.6 mm + Outer_Wafer_TransverseStrips= 605 + Outer_Wafer_LongitudinalStrips= 325 + Chamber_Thickness= 3 mm + Chamber_Cylinder_Length= 360 mm + Chamber_Radius= 180 mm + Chamber_ExitTube_Radius= 79.5 mm + Chamber_ExitTube_Length= 100 mm + Chamber_Flange_Inner_Radius= 50 mm + Chamber_Sphere_Radius= 220 mm + Chamber_Sphere_Shift= 60 mm + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Alias InnerPhi + Action= Copy + Value= 0 60 120 180 240 300 + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Strasse Inner + Radius= 30 mm + Z= 66.0 mm + Phi= @InnerPhi deg + Shift= 0 mm + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Alias OuterPhi + Action= Copy + Value= 0 60 120 180 240 300 + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Strasse Outer + Radius= 60 mm + Z= 78.0 mm + Phi= @OuterPhi deg + Shift= 0 mm + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Strasse Chamber + Z= -30 mm + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Catana CSV + Path= geometry/Catana.csv + Pos= 0 0 100 mm + Rshift= 100 micrometer + + diff --git a/Projects/Strasse/macro/CalculateDetectorOffset.cxx b/Projects/Strasse/macro/CalculateDetectorOffset.cxx new file mode 100644 index 0000000000000000000000000000000000000000..97dab461602c0cde1e36d5f7fcd9b6080679b92a --- /dev/null +++ b/Projects/Strasse/macro/CalculateDetectorOffset.cxx @@ -0,0 +1,255 @@ +#include <iostream> +#include <ctime> +#include <cstdlib> +using namespace std; + +// ROOT headers +#include "TString.h" + +// nptool headers +#include "NPInputParser.h" + +using namespace NPL; + + +void CalculateDetectorOffset(const char * fname = "strasse_optimized"){ + + // Open output ROOT file from NPTool simulation run + string path = ""; + string inFileName = fname; + inFileName += ".detector"; + + + InputParser *inParser = new InputParser(inFileName,true); + vector<NPL::InputBlock*> blocks_info = inParser->GetAllBlocksWithTokenAndValue("Strasse","Info"); + + if(blocks_info.size()>1){ + cout << "ERROR: can only accepte one info block, " << blocks_info.size() << " info block founds." << endl; + exit(1); + } + + + vector<string> info = { + "Inner_Wafer_Length", + "Inner_Wafer_Width", + "Inner_Wafer_Thickness", + "Inner_Wafer_AlThickness", + "Inner_Wafer_PADExternal", + "Inner_Wafer_PADInternal", + "Inner_Wafer_GuardRing", + "Inner_PCB_PortWidth", + "Inner_PCB_StarboardWidth", + "Inner_PCB_BevelAngle", + "Inner_PCB_UpstreamWidth", + "Inner_PCB_DownstreamWidth", + "Inner_PCB_MidWidth", + "Inner_PCB_Thickness", + "Inner_Wafer_TransverseStrips", + "Inner_Wafer_LongitudinalStrips", + "Outer_Wafer_Length", + "Outer_Wafer_Width", + "Outer_Wafer_Thickness", + "Outer_Wafer_AlThickness", + "Outer_Wafer_PADExternal", + "Outer_Wafer_PADInternal", + "Outer_Wafer_GuardRing", + "Outer_PCB_PortWidth", + "Outer_PCB_StarboardWidth", + "Outer_PCB_BevelAngle", + "Outer_PCB_UpstreamWidth", + "Outer_PCB_DownstreamWidth", + "Outer_PCB_MidWidth", + "Outer_PCB_Thickness", + "Outer_Wafer_TransverseStrips", + "Outer_Wafer_LongitudinalStrips", + "Chamber_Thickness", + "Chamber_Cylinder_Length", + "Chamber_Radius", + "Chamber_ExitTube_Radius", + "Chamber_ExitTube_Length", + "Chamber_Flange_Inner_Radius", + "Chamber_Sphere_Radius", + "Chamber_Sphere_Shift" + }; + + //////////////////// + // Inner Detector // + //////////////////// + // Wafer parameter + double Inner_Wafer_Length=-999; + double Inner_Wafer_Width=-999; + double Inner_Wafer_Thickness=-999; + double Inner_Wafer_AlThickness=-999; + double Inner_Wafer_PADExternal=-999; + double Inner_Wafer_PADInternal=-999; + double Inner_Wafer_GuardRing=-999; + + // PCB parameter + double Inner_PCB_PortWidth=-999; + double Inner_PCB_StarboardWidth=-999; + double Inner_PCB_BevelAngle=-999; + double Inner_PCB_UpstreamWidth=-999; + double Inner_PCB_DownstreamWidth=-999; + double Inner_PCB_MidWidth=-999; + double Inner_PCB_Thickness=-999; + double Inner_Wafer_TransverseStrips=-999; + double Inner_Wafer_LongitudinalStrips=-999; + + //////////////////// + // Outer Detector // + //////////////////// + // Wafer parameter + double Outer_Wafer_Length=-999; + double Outer_Wafer_Width=-999; + double Outer_Wafer_Thickness=-999; + double Outer_Wafer_AlThickness=-999; + double Outer_Wafer_PADExternal=-999; + double Outer_Wafer_PADInternal=-999; + double Outer_Wafer_GuardRing=-999; + + // PCB parameter + double Outer_PCB_PortWidth=-999; + double Outer_PCB_StarboardWidth=-999; + double Outer_PCB_BevelAngle=-999; + double Outer_PCB_UpstreamWidth=-999; + double Outer_PCB_DownstreamWidth=-999; + double Outer_PCB_MidWidth=-999; + double Outer_PCB_Thickness=-999; + double Outer_Wafer_TransverseStrips=-999; + double Outer_Wafer_LongitudinalStrips=-999; + + // Vacuum Chamber // + double Chamber_Thickness=-999; + double Chamber_Cylinder_Length=-999; + double Chamber_Radius=-999; + double Chamber_ExitTube_Radius=-999; + double Chamber_ExitTube_Length=-999; + double Chamber_Flange_Inner_Radius=-999; + double Chamber_Sphere_Radius=-999; + double Chamber_Sphere_Shift=-999; + + if(blocks_info[0]->HasTokenList(info)){ + cout << endl << "//// Strasse info block" << endl; + Inner_Wafer_Length = blocks_info[0]->GetDouble("Inner_Wafer_Length","mm"); + Inner_Wafer_Width = blocks_info[0]->GetDouble("Inner_Wafer_Width","mm"); + Inner_Wafer_Thickness = blocks_info[0]->GetDouble("Inner_Wafer_Thickness","micrometer"); + Inner_Wafer_AlThickness = blocks_info[0]->GetDouble("Inner_Wafer_AlThickness","micrometer"); + Inner_Wafer_PADExternal = blocks_info[0]->GetDouble("Inner_Wafer_PADExternal","mm"); + Inner_Wafer_PADInternal = blocks_info[0]->GetDouble("Inner_Wafer_PADInternal","mm"); + Inner_Wafer_GuardRing = blocks_info[0]->GetDouble("Inner_Wafer_GuardRing","mm"); + Inner_Wafer_TransverseStrips = blocks_info[0]->GetInt("Inner_Wafer_TransverseStrips"); + Inner_Wafer_LongitudinalStrips = blocks_info[0]->GetInt("Inner_Wafer_LongitudinalStrips"); + Inner_PCB_PortWidth = blocks_info[0]->GetDouble("Inner_PCB_PortWidth","mm"); + Inner_PCB_StarboardWidth = blocks_info[0]->GetDouble("Inner_PCB_StarboardWidth","mm"); + Inner_PCB_BevelAngle = blocks_info[0]->GetDouble("Inner_PCB_BevelAngle","mm"); + Inner_PCB_UpstreamWidth = blocks_info[0]->GetDouble("Inner_PCB_UpstreamWidth","mm"); + Inner_PCB_DownstreamWidth = blocks_info[0]->GetDouble("Inner_PCB_DownstreamWidth","mm"); + Inner_PCB_MidWidth = blocks_info[0]->GetDouble("Inner_PCB_MidWidth","mm"); + Inner_PCB_Thickness = blocks_info[0]->GetDouble("Inner_PCB_Thickness","mm"); + Outer_Wafer_Length = blocks_info[0]->GetDouble("Outer_Wafer_Length","mm"); + Outer_Wafer_Width = blocks_info[0]->GetDouble("Outer_Wafer_Width","mm"); + Outer_Wafer_Thickness = blocks_info[0]->GetDouble("Outer_Wafer_Thickness","mm"); + Outer_Wafer_AlThickness = blocks_info[0]->GetDouble("Outer_Wafer_AlThickness","micrometer"); + Outer_Wafer_PADExternal = blocks_info[0]->GetDouble("Outer_Wafer_PADExternal","mm"); + Outer_Wafer_PADInternal = blocks_info[0]->GetDouble("Outer_Wafer_PADInternal","mm"); + Outer_Wafer_GuardRing = blocks_info[0]->GetDouble("Outer_Wafer_GuardRing","mm"); + Outer_Wafer_TransverseStrips = blocks_info[0]->GetInt("Outer_Wafer_TransverseStrips"); + Outer_Wafer_LongitudinalStrips = blocks_info[0]->GetInt("Outer_Wafer_LongitudinalStrips"); + Outer_PCB_PortWidth = blocks_info[0]->GetDouble("Outer_PCB_PortWidth","mm"); + Outer_PCB_StarboardWidth = blocks_info[0]->GetDouble("Outer_PCB_StarboardWidth","mm"); + Outer_PCB_BevelAngle = blocks_info[0]->GetDouble("Outer_PCB_BevelAngle","deg"); + Outer_PCB_UpstreamWidth = blocks_info[0]->GetDouble("Outer_PCB_UpstreamWidth","mm"); + Outer_PCB_DownstreamWidth = blocks_info[0]->GetDouble("Outer_PCB_DownstreamWidth","mm"); + Outer_PCB_MidWidth = blocks_info[0]->GetDouble("Outer_PCB_MidWidth","mm"); + Outer_PCB_Thickness = blocks_info[0]->GetDouble("Outer_PCB_Thickness","mm"); + Chamber_Thickness= blocks_info[0]->GetDouble("Chamber_Thickness","mm"); + Chamber_Cylinder_Length= blocks_info[0]->GetDouble("Chamber_Cylinder_Length","mm"); + Chamber_Radius= blocks_info[0]->GetDouble("Chamber_Radius","mm"); + Chamber_ExitTube_Radius=blocks_info[0]->GetDouble("Chamber_ExitTube_Radius","mm"); + Chamber_ExitTube_Length=blocks_info[0]->GetDouble("Chamber_ExitTube_Length","mm"); + Chamber_Flange_Inner_Radius=blocks_info[0]->GetDouble("Chamber_Flange_Inner_Radius","mm"); + Chamber_Sphere_Radius=blocks_info[0]->GetDouble("Chamber_Sphere_Radius","mm"); + Chamber_Sphere_Shift=blocks_info[0]->GetDouble("Chamber_Sphere_Shift","mm"); + } + + + + + vector<NPL::InputBlock*> starget = inParser->GetAllBlocksWithToken("Target"); + + double TargetThickness = -999; + double TargetX = -999; + double TargetY = -999; + double TargetZ = -999; + + if(starget.size()==1){ + cout << "//// TARGET ////" << endl; + cout << "//// Solid Target found " << endl; + vector<string> token = {"Thickness","Radius","Material","Angle","X","Y","Z"}; + if(starget[0]->HasTokenList(token)){ + TargetThickness= starget[0]->GetDouble("Thickness","mm"); + TargetX=starget[0]->GetDouble("X","mm"); + TargetY=starget[0]->GetDouble("Y","mm"); + TargetZ=starget[0]->GetDouble("Z","mm"); + } + else{ + cout << "ERROR: Target token list incomplete, check your input file" << endl; + exit(1); + } + } + + +////////////////////////////////////////////////// + + +double d_TargetFront_InnerActive = 15; //mm +double d_TargetFront_OuterActive = 43; //mm + +double InnerTotalLength = + Inner_PCB_UpstreamWidth + + Inner_Wafer_Length * 2 + + Inner_PCB_MidWidth + + Inner_PCB_DownstreamWidth; + +double d_TargetCenter_InnerCenter = + - TargetThickness/2. + + d_TargetFront_InnerActive + + InnerTotalLength/2. + - Inner_Wafer_GuardRing + - Inner_PCB_UpstreamWidth; + +double OuterTotalLength = + Outer_PCB_UpstreamWidth + + Outer_Wafer_Length * 2 + + Outer_PCB_MidWidth + + Outer_PCB_DownstreamWidth; + +double d_TargetCenter_OuterCenter = + - TargetThickness/2. + + d_TargetFront_OuterActive + + OuterTotalLength/2. + - Outer_Wafer_GuardRing + - Outer_PCB_UpstreamWidth; + + +cout<<endl; +cout<< "---------- INPUT DISTANCES (mm) -------------"<<endl; +cout<<endl; +cout<<"Target Thickness : "<<TargetThickness<<endl; +cout<<"Beginning Target - Beginning Inner Active : "<<d_TargetFront_InnerActive<<endl; +cout<<"Beginning Target - Beginning Outer Active : "<<d_TargetFront_OuterActive<<endl; +cout<<endl; +cout<< "--------- CALCULATED DISTANCES (mm) -----------"<<endl; + +cout << "InnerTotalLength = "<<InnerTotalLength<<endl; +cout << "d_TargetCenter_InnerCenter = "<<d_TargetCenter_InnerCenter<<endl; +cout<<endl; + +cout << "OuterTotalLength = "<<OuterTotalLength<<endl; +cout << "d_TargetCenter_OuterCenter = "<<d_TargetCenter_OuterCenter<<endl; +cout<<endl; +cout<< "---------------------------------- -----------"<<endl; +cout<<"Remark: this calculation assumes that the center of target is at (0,0,0)"<<endl; +} + + diff --git a/Projects/Strasse/macro/CheckSim.cxx b/Projects/Strasse/macro/CheckSim.cxx new file mode 100644 index 0000000000000000000000000000000000000000..5b0f07c253c6f4e082524baacebab80aa888f3a7 --- /dev/null +++ b/Projects/Strasse/macro/CheckSim.cxx @@ -0,0 +1,49 @@ +{ +gStyle->SetPalette(1); +//TFile *file= new TFile("../../Outputs/Simulation/test_ref.root"); +TFile *file= new TFile("../../Outputs/Simulation/test_optimized.root"); +TTree *tree = (TTree*)file->Get("SimulatedTree"); + +TCanvas *c1 = new TCanvas("c1","c1",1000,1000); +c1->Divide(4,4); +c1->cd(1); +tree->Draw("fRC_Beam_Reaction_Energy:fRC_Vertex_Position_Z>>h1(200,-3.1,3.1,220,,)","","colz"); +c1->cd(2); +tree->Draw("fRC_Vertex_Position_Y:fRC_Vertex_Position_Z>>h2","",""); +c1->cd(3); +tree->Draw("fRC_Vertex_Position_X:fRC_Vertex_Position_Z>>h3","",""); +c1->cd(4); +tree->Draw("fDetected_Position_Y:fDetected_Position_X>>h4","","colz"); +c1->cd(5); +tree->Draw("fDetected_Position_Y:fDetected_Position_Z>>h5(1200,-70,230,280,-70,70)","","colz"); +c1->cd(6); +tree->Draw("fInner_TE_StripNbr:fDetected_Position_Z>>h6","","colz"); +c1->cd(7); +tree->Draw("fInner_LE_StripNbr:fDetected_Position_X>>h7","","colz"); +c1->cd(8); +tree->Draw("Strasse.GetOuterMultTEnergy()+Strasse.GetInnerMultTEnergy()>>h8(6,0,6)","",""); +c1->cd(9); +tree->Draw("fInner_LE_StripNbr>>h9(1250,0,1250)","",""); +c1->cd(10); +tree->Draw("fInner_TE_StripNbr>>h10(1250,0,1250)","",""); +c1->cd(11); +tree->Draw("fOuter_LE_StripNbr>>h11(1250,0,1250)","",""); +c1->cd(12); +tree->Draw("fOuter_TE_StripNbr>>h12(1250,0,1250)","",""); +c1->cd(13); +tree->Draw("fOuter_TE_StripNbr:fDetected_Position_Z>>h13","","colz"); +c1->cd(14); +tree->Draw("fOuter_LE_StripNbr:fDetected_Position_X>>h14","","colz"); +c1->cd(15); +tree->Draw("fRC_Theta[1]>>h15","",""); +tree->Draw("fRC_Theta[1]>>h16","Strasse.GetOuterMultTEnergy()+Strasse.GetInnerMultTEnergy()","same"); +h16->SetLineColor(2); +h16->Scale(1./4);; +c1->cd(16); +tree->Draw("fRC_Theta[0]>>h17","",""); +tree->Draw("fRC_Theta[0]>>h18","Strasse.GetOuterMultTEnergy()+Strasse.GetInnerMultTEnergy()","same"); +h18->SetLineColor(2); +h18->Scale(1./4);; + + +} diff --git a/Projects/Strasse/macro/Control.cxx b/Projects/Strasse/macro/Control.cxx new file mode 100644 index 0000000000000000000000000000000000000000..4dded1f5d16caba29ad868744e226b1960725fef --- /dev/null +++ b/Projects/Strasse/macro/Control.cxx @@ -0,0 +1,68 @@ +void Control(){ + TFile* file = TFile::Open("../../Outputs/Analysis/PhysicsTree.root"); + TTree* PhysicsTree= (TTree*) file->FindObjectAny("PhysicsTree"); + string cond = "InnerPosX!=-1000"; +/* + TCanvas* cInner = new TCanvas("ControlInner","ControlInner",1000,1000); + cInner->Divide(2,2); + cInner->cd(1); + PhysicsTree->Draw("InnerPosX:fDetected_Position_X",cond.c_str(),"col") ; + cInner->cd(2); + PhysicsTree->Draw("InnerPosY:fDetected_Position_Y",cond.c_str(),"col") ; + cInner->cd(3); + PhysicsTree->Draw("InnerPosZ:fDetected_Position_Z",cond.c_str(),"col") ; + cInner->cd(4); + PhysicsTree->Draw("InnerPosY:InnerPosX:InnerPosZ", cond.c_str(),""); + + TCanvas* cOuter = new TCanvas("ControlOuter","ControlOuter",1000,1000); + cOuter->Divide(2,2); + cond = "OuterPosX!=-1000"; + cOuter->cd(1); + PhysicsTree->Draw("OuterPosX:fDetected_Position_X[3]",cond.c_str(),"col") ; + cOuter->cd(2); + PhysicsTree->Draw("OuterPosY:fDetected_Position_Y[3]",cond.c_str(),"col") ; + cOuter->cd(3); + PhysicsTree->Draw("OuterPosZ:fDetected_Position_Z[3]",cond.c_str(),"col") ; + cOuter->cd(4); + PhysicsTree->Draw("OuterPosY:OuterPosX:OuterPosZ", cond.c_str(),""); + + TCanvas* cVertex = new TCanvas("ControlVertex","ControlVertex",1000,1000); + cVertex->Divide(2,2); + cond = "VertexX!=-1000"; + cVertex->cd(1); + PhysicsTree->Draw("VertexX-fRC_Vertex_Position_X>>hx(500,-2,2)",cond.c_str(),"col") ; + cVertex->cd(2); + PhysicsTree->Draw("VertexY-fRC_Vertex_Position_Y>>hy(500,-2,2)",cond.c_str(),"col") ; + cVertex->cd(3); + PhysicsTree->Draw("VertexZ-fRC_Vertex_Position_Z>>hz(5000,-20,20)",cond.c_str(),"col") ; + cVertex->cd(4); + + PhysicsTree->Draw("Distance>>hd(500,0,80)", cond.c_str(),""); + //PhysicsTree->Draw("VertexY:VertexX:VertexZ", cond.c_str(),""); + + TCanvas* cdelta= new TCanvas("ControlDelta","ControlDelta",1000,1000); + cdelta->Divide(2,2); + cond = "deltaX!=-1000"; + cdelta->cd(1); + PhysicsTree->Draw("deltaX>>dx(500,-0.01,0.01)",cond.c_str(),"col") ; + cdelta->cd(2); + PhysicsTree->Draw("deltaY>>dy(500,-0.01,0.01)",cond.c_str(),"col") ; + cdelta->cd(3); + PhysicsTree->Draw("deltaZ>>dz(500,-0.01,0.01)",cond.c_str(),"col") ; + cdelta->cd(4); + PhysicsTree->Draw("Distance>>hd(500,0,0.01)", cond.c_str(),""); +*/ + TCanvas* ctheta= new TCanvas("ControlTheta","ControlTheta",1000,1000); + cond = "Theta12!=-1000"; + PhysicsTree->Draw("Theta12>>ht",cond.c_str(),"col") ; + + +/* + TCanvas* c2 = new TCanvas("Control 2", "Control2",500,500,2000,1000); + c2->Divide(2,1); + c2->cd(1); + PhysicsTree->Draw("VertexY:VertexX:VertexZ",cond.c_str()); + c2->cd(2); + +*/ +} diff --git a/Projects/Strasse/macro/Shift.cxx b/Projects/Strasse/macro/Shift.cxx new file mode 100644 index 0000000000000000000000000000000000000000..235948643365b1bde8a28a90227d0b8e70b0cd94 --- /dev/null +++ b/Projects/Strasse/macro/Shift.cxx @@ -0,0 +1,24 @@ +void Shift(){ + TFile* file_ok = TFile::Open("../../Outputs/Analysis/strasse_ok.root"); + TFile* file_shifted = TFile::Open("../../Outputs/Analysis/strasse_shifted.root"); + TTree* ok= (TTree*) file_ok->FindObjectAny("PhysicsTree"); + TTree* shifted= (TTree*) file_shifted->FindObjectAny("PhysicsTree"); + TCanvas* ctheta= new TCanvas("ControlTheta","ControlTheta",2000,1000); + ctheta->Divide(2,1); + ctheta->cd(1); + string cond = "Theta12!=-1000"; + ok->Draw("Theta12>>ht(5000)",cond.c_str(),"") ; + shifted->Draw("Theta12>>hts(5000)",cond.c_str(),"same") ; + TH1* hts= (TH1*) gDirectory->FindObjectAny("hts"); + hts->SetFillColor(kOrange-3); + hts->SetLineColor(kOrange-3); + ctheta->cd(2); + cond = "deltaPhi!=-1000"; + ok->Draw("deltaPhi>>hp(5000)",cond.c_str(),"") ; + shifted->Draw("deltaPhi>>hps(5000)",cond.c_str(),"same") ; + TH1* hps= (TH1*) gDirectory->FindObjectAny("hps"); + hps->SetFillColor(kOrange-3); + hps->SetLineColor(kOrange-3); + + +} diff --git a/Projects/Strasse/reaction/C12_p2p.reaction b/Projects/Strasse/reaction/C12_p2p.reaction new file mode 100755 index 0000000000000000000000000000000000000000..47d81151a1fb81d022acb2cef5a7c7b067aae6cf --- /dev/null +++ b/Projects/Strasse/reaction/C12_p2p.reaction @@ -0,0 +1,29 @@ +%%%%%%%%%%%%%%%%%% QFS Example in progress %%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Beam + Particle= 12C + Energy= 4800 MeV + SigmaEnergy= 0 MeV + SigmaThetaX= 0.1 deg + SigmaPhiY= 0.1 deg + SigmaX= 5 mm + SigmaY= 5 mm + MeanThetaX= 0 deg + MeanPhiY= 0 deg + MeanX= 0 mm + MeanY= 0 mm + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +QFSReaction + Beam= 12C + Target= 1H + Scattered= 1H + KnockedOut= 1H + Heavy= 11B + ExcitationEnergyBeam= 0.0 MeV + ExcitationEnergyHeavy= 0.0 MeV + MomentumSigma= 50.0 + ShootHeavy= 1 + ShootLight= 1 + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/Projects/TACTIC/Analysis.cxx b/Projects/TACTIC/Analysis.cxx new file mode 100644 index 0000000000000000000000000000000000000000..08fbb0f61c06d42fc8eb8e790dc2bb71fd0ee627 --- /dev/null +++ b/Projects/TACTIC/Analysis.cxx @@ -0,0 +1,68 @@ +/***************************************************************************** + * 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: XAUTHORX contact address: XMAILX * + * * + * Creation Date : XMONTHX XYEARX * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class describe TACTIC analysis project * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + *****************************************************************************/ + +#include<iostream> +using namespace std; +#include"Analysis.h" +#include"NPAnalysisFactory.h" +#include"NPDetectorManager.h" +//////////////////////////////////////////////////////////////////////////////// +Analysis::Analysis(){ +} +//////////////////////////////////////////////////////////////////////////////// +Analysis::~Analysis(){ +} + +//////////////////////////////////////////////////////////////////////////////// +void Analysis::Init(){ + TACTIC= (TTACTICPhysicsPhysics*) m_DetectorManager->GetDetector("TACTIC"); +} + +//////////////////////////////////////////////////////////////////////////////// +void Analysis::TreatEvent(){ +} + +//////////////////////////////////////////////////////////////////////////////// +void Analysis::End(){ +} + + +//////////////////////////////////////////////////////////////////////////////// +// Construct Method to be pass to the DetectorFactory // +//////////////////////////////////////////////////////////////////////////////// +NPL::VAnalysis* Analysis::Construct(){ + return (NPL::VAnalysis*) new Analysis(); +} + +//////////////////////////////////////////////////////////////////////////////// +// Registering the construct method to the factory // +//////////////////////////////////////////////////////////////////////////////// +extern "C"{ +class proxy{ + public: + proxy(){ + NPL::AnalysisFactory::getInstance()->SetConstructor(Analysis::Construct); + } +}; + +proxy p; +} + diff --git a/Projects/TACTIC/Analysis.h b/Projects/TACTIC/Analysis.h new file mode 100644 index 0000000000000000000000000000000000000000..eda0a4f8d513a9ffac10ba5281229e8ba67e3f0e --- /dev/null +++ b/Projects/TACTIC/Analysis.h @@ -0,0 +1,42 @@ +#ifndef Analysis_h +#define Analysis_h +/***************************************************************************** + * 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: XAUTHORX contact address: XMAILX * + * * + * Creation Date : XMONTHX XYEARX * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * This class describe TACTIC analysis project * + * * + *---------------------------------------------------------------------------* + * Comment: * + * * + *****************************************************************************/ + +#include"NPVAnalysis.h" +#include"TTACTICPhysics.h" +class Analysis: public NPL::VAnalysis{ + public: + Analysis(); + ~Analysis(); + + public: + void Init(); + void TreatEvent(); + void End(); + + static NPL::VAnalysis* Construct(); + + private: + TTACTICPhysics* TACTIC; + +}; +#endif diff --git a/Projects/TACTIC/CMakeLists.txt b/Projects/TACTIC/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..22c74affdfc45019bdda2594f8439c52d4ab97ec --- /dev/null +++ b/Projects/TACTIC/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_minimum_required (VERSION 2.8) +# Setting the policy to match Cmake version +cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}) +# include the default NPAnalysis cmake file +include("../../NPLib/ressources/CMake/NPAnalysis.cmake") diff --git a/Projects/TACTIC/TACTIC.detector b/Projects/TACTIC/TACTIC.detector new file mode 100644 index 0000000000000000000000000000000000000000..d9a48d30026cfb6f32bcd0f2550b5d688b258413 --- /dev/null +++ b/Projects/TACTIC/TACTIC.detector @@ -0,0 +1,25 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +Target + THICKNESS= 10 micrometer + RADIUS= 20 mm + MATERIAL= CD2 + ANGLE= 0 deg + X= 0 mm + Y= 0 mm + Z= 0 mm +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +TACTIC + POS= 0 0 350 mm + Shape= Square +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +TACTIC + POS = 35 35 35 cm + Shape= Square +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +TACTIC + R= 350 mm + THETA= 90 deg + PHI= 63 deg + Shape= Cylindrical +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +