From 38aaf777c00c670198eaf6325e29b378001e8a42 Mon Sep 17 00:00:00 2001 From: Morfouace <morfouac@ipno.in2p3.fr> Date: Tue, 28 Aug 2018 10:26:06 +0200 Subject: [PATCH] ! Adding Actar files for analysis and simulation ! Adding a new folder TrackReconstruction for Tracking algorithm --- Inputs/EventGenerator/18Opp.reaction | 2 +- Inputs/EventGenerator/proton.source | 6 +- NPLib/CMakeLists.txt | 21 +- NPLib/Detectors/Actar/CMakeLists.txt | 7 +- NPLib/Detectors/Actar/MEventReduced.h | 40 + NPLib/Detectors/Actar/MTreeStructureLinkDef.h | 12 + NPLib/Detectors/Actar/TActarData.cxx | 23 +- NPLib/Detectors/Actar/TActarData.h | 60 +- NPLib/Detectors/Actar/TActarPhysics.cxx | 601 +++++++++----- NPLib/Detectors/Actar/TActarPhysics.h | 206 +++-- NPLib/Detectors/Actar/TActarSpectra.cxx | 24 +- NPLib/TrackReconstruction/CMakeLists.txt | 6 + NPLib/TrackReconstruction/NPRansac.cxx | 774 ++++++++++++++++++ NPLib/TrackReconstruction/NPRansac.h | 117 +++ NPLib/TrackReconstruction/NPTrack.cxx | 210 +++++ NPLib/TrackReconstruction/NPTrack.h | 96 +++ .../NPTrackReconstructionLinkDef.h | 4 + NPLib/scripts/build_dict.sh | 4 +- NPSimulation/Core/MaterialManager.cc | 16 +- NPSimulation/Core/Target.cc | 4 +- NPSimulation/Detectors/Actar/Actar.cc | 703 ++++++++++------ NPSimulation/Detectors/Actar/Actar.hh | 37 +- .../EventGenerator/EventGeneratorIsotropic.cc | 7 +- .../EventGenerator/EventGeneratorIsotropic.hh | 1 + NPSimulation/Process/BeamReaction.cc | 4 +- NPSimulation/Scorers/CMakeLists.txt | 2 +- NPSimulation/Scorers/TPCScorers.cc | 119 +++ NPSimulation/Scorers/TPCScorers.hh | 94 +++ Projects/Actar/Analysis.cxx | 168 +++- Projects/Actar/Analysis.h | 60 +- 30 files changed, 2745 insertions(+), 683 deletions(-) create mode 100644 NPLib/Detectors/Actar/MEventReduced.h create mode 100644 NPLib/Detectors/Actar/MTreeStructureLinkDef.h create mode 100644 NPLib/TrackReconstruction/CMakeLists.txt create mode 100644 NPLib/TrackReconstruction/NPRansac.cxx create mode 100644 NPLib/TrackReconstruction/NPRansac.h create mode 100644 NPLib/TrackReconstruction/NPTrack.cxx create mode 100644 NPLib/TrackReconstruction/NPTrack.h create mode 100644 NPLib/TrackReconstruction/NPTrackReconstructionLinkDef.h create mode 100644 NPSimulation/Scorers/TPCScorers.cc create mode 100644 NPSimulation/Scorers/TPCScorers.hh diff --git a/Inputs/EventGenerator/18Opp.reaction b/Inputs/EventGenerator/18Opp.reaction index 488eed07e..13be99a5f 100644 --- a/Inputs/EventGenerator/18Opp.reaction +++ b/Inputs/EventGenerator/18Opp.reaction @@ -4,7 +4,7 @@ %%Beam energy given in MeV ; Excitation in MeV Beam Particle= 18O - Energy= 137.88 + Energy= 59.4 SigmaEnergy= 0 SigmaThetaX= 0 SigmaPhiY= 0 diff --git a/Inputs/EventGenerator/proton.source b/Inputs/EventGenerator/proton.source index 7b62f807a..7a4e1e53e 100644 --- a/Inputs/EventGenerator/proton.source +++ b/Inputs/EventGenerator/proton.source @@ -4,10 +4,10 @@ % Energy are given in MeV , Position in mm % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Isotropic - EnergyLow= 30 - EnergyHigh= 80 + EnergyLow= 20 + EnergyHigh= 25 HalfOpenAngleMin= 0 - HalfOpenAngleMax= 1 + HalfOpenAngleMax= 180 x0= 0 y0= 0 z0= 0 diff --git a/NPLib/CMakeLists.txt b/NPLib/CMakeLists.txt index fd1349561..0f10c8e49 100644 --- a/NPLib/CMakeLists.txt +++ b/NPLib/CMakeLists.txt @@ -2,6 +2,7 @@ cmake_minimum_required (VERSION 2.8) include(CheckCXXCompilerFlag) project(NPLib CXX) set(CMAKE_BUILD_TYPE Release) + # Setting the policy to match Cmake version cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}) @@ -18,23 +19,6 @@ set(NPLIB_VERSION_DETA 45) configure_file(Core/NPLibVersion.h.in Core/NPLibVersion.h @ONLY) set(DETLIST ${ETLIST}) -#activate Multithreading (on by default) -if(NOT DEFINED NPMULTITHREADING) - set(NPMULTITHREADING 1) - else() - set(NPMULTITHREADING ${NPMULTITHREADING}) -endif() - -if(NPMULTITHREADING) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DNPMULTITHREADING=1") - message("Building application with MultiThreading Support") - else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DNPMULTITHREADING=0") - message("Building application with no MutilThreading Support") -endif() - - - string(COMPARE EQUAL "${DETLIST}" "" rdet) if(rdet) message("Building all detectors") @@ -73,11 +57,12 @@ ENDMACRO() # Add include directories to all target include_directories("Core/") include_directories("Physics/") +include_directories("TrackReconstruction/") include_directories("Online/") # Call the macro subdirlist(SUB_DIRECTORY ${CMAKE_BINARY_DIR}) -set(SUB_DIRECTORY ${SUB_DIRECTORY} Core Physics Calibration Online Utility) +set(SUB_DIRECTORY ${SUB_DIRECTORY} Core Physics TrackReconstruction Calibration Online Utility) # Add each sub folder to the project set(TARGET_LIST "") foreach(subdir ${SUB_DIRECTORY}) diff --git a/NPLib/Detectors/Actar/CMakeLists.txt b/NPLib/Detectors/Actar/CMakeLists.txt index a1b027f69..3a0cfd553 100644 --- a/NPLib/Detectors/Actar/CMakeLists.txt +++ b/NPLib/Detectors/Actar/CMakeLists.txt @@ -1,6 +1,7 @@ add_custom_command(OUTPUT TActarPhysicsDict.cxx COMMAND ../../scripts/build_dict.sh TActarPhysics.h TActarPhysicsDict.cxx TActarPhysics.rootmap libNPActar.dylib DEPENDS TActarPhysics.h) add_custom_command(OUTPUT TActarDataDict.cxx COMMAND ../../scripts/build_dict.sh TActarData.h TActarDataDict.cxx TActarData.rootmap libNPActar.dylib DEPENDS TActarData.h) -add_library(NPActar SHARED TActarSpectra.cxx TActarData.cxx TActarPhysics.cxx TActarDataDict.cxx TActarPhysicsDict.cxx ) -target_link_libraries(NPActar ${ROOT_LIBRARIES} NPCore) -install(FILES TActarData.h TActarPhysics.h TActarSpectra.h DESTINATION ${CMAKE_INCLUDE_OUTPUT_DIRECTORY}) +add_custom_command(OUTPUT MEventReducedDict.cxx COMMAND ../../scripts/build_dict.sh MEventReduced.h MEventReducedDict.cxx MEventReduced.rootmap libNPActar.dylib MTreeStructureLinkDef.h DEPENDS MEventReduced.h) +add_library(NPActar SHARED TActarSpectra.cxx TActarData.cxx TActarPhysics.cxx TActarDataDict.cxx TActarPhysicsDict.cxx MEventReducedDict.cxx) +target_link_libraries(NPActar ${ROOT_LIBRARIES} NPCore NPTrackReconstruction) +install(FILES TActarData.h TActarPhysics.h TActarSpectra.h MEventReduced.h DESTINATION ${CMAKE_INCLUDE_OUTPUT_DIRECTORY}) diff --git a/NPLib/Detectors/Actar/MEventReduced.h b/NPLib/Detectors/Actar/MEventReduced.h new file mode 100644 index 000000000..0d642c10a --- /dev/null +++ b/NPLib/Detectors/Actar/MEventReduced.h @@ -0,0 +1,40 @@ +#ifndef MEVENTREDUCED_H +#define MEVENTREDUCED_H + +#include <stdio.h> +#include <iostream> +#include <cstdlib> +#include <vector> +#include <TObject.h> + +using namespace std; + +class ReducedData: public TObject +{ + public: + ReducedData(){}; + virtual ~ReducedData(){}; + + unsigned short globalchannelid; + bool hasSaturation; + + std::vector<float> peakheight; + std::vector<float> peaktime; + + ClassDef(ReducedData,1); +}; + +class MEventReduced: public TObject +{ + public: + MEventReduced(){}; + virtual ~MEventReduced(){}; + unsigned long int event; + unsigned long int timestamp; + std::vector<ReducedData> CoboAsad; + + ClassDef(MEventReduced,1); +}; + + +#endif diff --git a/NPLib/Detectors/Actar/MTreeStructureLinkDef.h b/NPLib/Detectors/Actar/MTreeStructureLinkDef.h new file mode 100644 index 000000000..c9ec8b317 --- /dev/null +++ b/NPLib/Detectors/Actar/MTreeStructureLinkDef.h @@ -0,0 +1,12 @@ +#ifdef __CINT__ + +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; +#pragma link C++ nestedclasses; + +#pragma link C++ class ReducedData+; +#pragma link C++ class MEventReduced+; + + +#endif diff --git a/NPLib/Detectors/Actar/TActarData.cxx b/NPLib/Detectors/Actar/TActarData.cxx index a9462d0ee..9c569553b 100644 --- a/NPLib/Detectors/Actar/TActarData.cxx +++ b/NPLib/Detectors/Actar/TActarData.cxx @@ -6,7 +6,7 @@ *****************************************************************************/ /***************************************************************************** - * Original Author: Pierre Morfouace contact address: morfouac@nscl.msu.edu * + * Original Author: Pierre Morfouace contact address: morfouace@ganil.fr * * * * Creation Date : September 2017 * * Last update : * @@ -46,12 +46,10 @@ TActarData::~TActarData() { void TActarData::Clear() { // Charge fActar_PadNumber.clear(); - fActar_PadRow.clear(); - fActar_PadColumn.clear(); + fActar_PadX.clear(); + fActar_PadY.clear(); + fActar_PadZ.clear(); fActar_PadCharge.clear(); - fActar_PadTime.clear(); - fActar_dig_Charge.clear(); - fActar_dig_Time.clear(); fSilicon_Energy.clear(); fSilicon_Time.clear(); @@ -61,13 +59,6 @@ void TActarData::Clear() { fCsI_CrystalNumber.clear(); } -//////////////////////////////////////////////////////////////////////////////// -TGraph* TActarData::GetChargeAsGraph(){ - TGraph* res = new TGraph (fActar_dig_Charge.size(),&fActar_dig_Time[0],&fActar_dig_Charge[0]); - res->Sort(); - return res; - -} ////////////////////////////////////////////////////////////////////// @@ -81,8 +72,10 @@ void TActarData::Dump() const { for (size_t i = 0 ; i < mysize ; i++){ cout << "Pad Number: " << fActar_PadNumber[i] - << " Charge: " << fActar_PadCharge[i] - << " Time: " << fActar_PadTime[i]; + << "Charge: " << fActar_PadCharge[i] + << " X: " << fActar_PadX[i] + << " Y: " << fActar_PadY[i] + << " Z: " << fActar_PadZ[i]; } } diff --git a/NPLib/Detectors/Actar/TActarData.h b/NPLib/Detectors/Actar/TActarData.h index 385512cd1..5674c6aa4 100644 --- a/NPLib/Detectors/Actar/TActarData.h +++ b/NPLib/Detectors/Actar/TActarData.h @@ -8,7 +8,7 @@ *****************************************************************************/ /***************************************************************************** - * Original Author: Pierre Morfouace contact address: morfouac@nscl.msu.edu * + * Original Author: Pierre Morfouace contact address: morfouace@ganil.fr * * * * Creation Date : September 2017 * * Last update : * @@ -37,14 +37,11 @@ class TActarData : public TObject { private: // Charge vector<int> fActar_PadNumber; - vector<int> fActar_PadTime; - vector<int> fActar_PadRow; - vector<int> fActar_PadColumn; + vector<int> fActar_PadX; + vector<int> fActar_PadY; + vector<int> fActar_PadZ; vector<double> fActar_PadCharge; - vector<double> fActar_dig_Time; - vector<double> fActar_dig_Charge; - vector<double> fSilicon_Energy; vector<int> fSilicon_DetectorNumber; vector<double> fSilicon_Time; @@ -83,25 +80,19 @@ class TActarData : public TObject { inline void SetPadNumber(const UShort_t& PadNbr){ fActar_PadNumber.push_back(PadNbr); };//! - // Row - inline void SetRowNumber(const UShort_t& RowNbr){ - fActar_PadRow.push_back(RowNbr); + // Row Y + inline void SetPadY(const UShort_t& RowNbr){ + fActar_PadY.push_back(RowNbr); } - // Column - inline void SetColumnNumber(const UShort_t& ColumnNbr){ - fActar_PadColumn.push_back(ColumnNbr); + // Column X + inline void SetPadX(const UShort_t& ColumnNbr){ + fActar_PadX.push_back(ColumnNbr); } - // Time - inline void SetTime(const Double_t& Time) { - fActar_PadTime.push_back(Time); + // Time Z + inline void SetPadZ(const Double_t& Time) { + fActar_PadZ.push_back(Time); };//! - // Digitizer - void AddEnergyPoint(double& E,double& T){ - fActar_dig_Charge.push_back(E); - fActar_dig_Time.push_back(T); - } - //Silicon inline void SetSiliconEnergy(const Double_t& Energy){ fSilicon_Energy.push_back(Energy); @@ -124,23 +115,20 @@ class TActarData : public TObject { ////////////////////// GETTERS //////////////////////// // Charge - inline UShort_t GetMultCharge() const - {return fActar_PadNumber.size();} - inline UShort_t Get_PadNumber(const unsigned int &i) const + inline UShort_t GetPadMult() const + {return fActar_PadX.size();} + inline UShort_t GetPadNumber(const unsigned int &i) const {return fActar_PadNumber[i];}//! - inline UShort_t Get_PadRow(const unsigned int &i) const - {return fActar_PadRow[i];}//! - inline UShort_t Get_PadColumn(const unsigned int &i) const - {return fActar_PadColumn[i];}//! - inline Double_t Get_Charge(const unsigned int &i) const + inline UShort_t GetPadX(const unsigned int &i) const + {return fActar_PadX[i];}//! + inline UShort_t GetPadY(const unsigned int &i) const + {return fActar_PadY[i];}//! + inline Double_t GetPadZ(const unsigned int &i) const + {return fActar_PadZ[i];}//! + inline Double_t GetPadCharge(const unsigned int &i) const {return fActar_PadCharge[i];}//! + - // Time - inline Double_t Get_Time(const unsigned int &i) const - {return fActar_PadTime[i];}//! - - inline vector<double> Get_dig_Charge() {return fActar_dig_Charge;} - TGraph* GetChargeAsGraph(); // Silicon inline Double_t Get_SiliconEnergy(const unsigned int &i) const diff --git a/NPLib/Detectors/Actar/TActarPhysics.cxx b/NPLib/Detectors/Actar/TActarPhysics.cxx index 644cbd4d1..4fc143b32 100644 --- a/NPLib/Detectors/Actar/TActarPhysics.cxx +++ b/NPLib/Detectors/Actar/TActarPhysics.cxx @@ -6,7 +6,7 @@ *****************************************************************************/ /***************************************************************************** - * Original Author: Pierre Morfouace contact address: morfouac@nscl.msu.edu * + * Original Author: Pierre Morfouace contact address: morfouace@ganil.fr * * * * Creation Date : September 2017 * * Last update : * @@ -47,305 +47,506 @@ ClassImp(TActarPhysics) /////////////////////////////////////////////////////////////////////////// TActarPhysics::TActarPhysics() - : m_EventData(new TActarData), - m_PreTreatedData(new TActarData), - m_EventPhysics(this), - m_Spectra(0), - m_E_RAW_Threshold(0), // adc channels - m_E_Threshold(0), // MeV - m_NumberOfDetectors(0) { +: m_EventData(new TActarData), +m_EventReduced(new MEventReduced), +m_PreTreatedData(new TActarData), +m_EventPhysics(this), + +m_Spectra(0), +fRecoRansac(1), +fRecoVisu(0), +fHitThreshold(20), +fQ_Threshold(0), +fT_Threshold(0), +fNumberOfPadsX(128), +fNumberOfPadsY(128), +fPadSizeX(2), +fPadSizeY(2), +fDriftVelocity(40), +fPressure(100), +fGas("iC4H10"), +m_NumberOfDetectors(0) { } /////////////////////////////////////////////////////////////////////////// /// A usefull method to bundle all operation to add a detector void TActarPhysics::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++; + // 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 TActarPhysics::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); + // 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 TActarPhysics::BuildSimplePhysicalEvent() { - BuildPhysicalEvent(); + BuildPhysicalEvent(); } /////////////////////////////////////////////////////////////////////////// void TActarPhysics::BuildPhysicalEvent() { - // apply thresholds and calibration - - PreTreat(); - - // match Charge and time together - unsigned int mysizeE = m_PreTreatedData->GetMultCharge(); - - for (UShort_t e = 0; e < mysizeE ; e++) { - PadNumber.push_back(m_PreTreatedData->Get_PadNumber(e)); - PadRow.push_back(m_PreTreatedData->Get_PadRow(e)); - PadColumn.push_back(m_PreTreatedData->Get_PadColumn(e)); - PadCharge.push_back(m_PreTreatedData->Get_Charge(e)); - PadTime.push_back(m_PreTreatedData->Get_Time(e)); - } - - HoughTransform(PadRow, PadColumn, PadTime); + + PreTreat(); + + //unsigned int mysize = m_PreTreatedData->GetPadMult(); + + /*for (unsigned int e = 0; e < mysize; e++) { + PadX.push_back(m_PreTreatedData->GetPadX(e)); + PadY.push_back(m_PreTreatedData->GetPadY(e)); + PadZ.push_back(m_PreTreatedData->GetPadZ(e)); + PadCharge.push_back(m_PreTreatedData->GetPadCharge(e)); + }*/ + + if(fRecoRansac && PadX.size()>fHitThreshold){ + m_Ransac->Init(PadX, PadY, PadZ, PadCharge); + m_Track = m_Ransac->SimpleRansac(); + } + + TrackMult = m_Track.size(); } /////////////////////////////////////////////////////////////////////////// void TActarPhysics::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(); - - // Charge - unsigned int mysize = m_EventData->GetMultCharge(); - - for (UShort_t i = 0; i < mysize ; ++i) { - if (m_EventData->Get_Charge(i) > m_E_RAW_Threshold) { - //Double_t Charge = Cal->ApplyCalibration("Actar/CHARGE"+NPL::itoa(m_EventData->Get_PadNumber(i)),m_EventData->Get_Charge(i)); - //Double_t Time= Cal->ApplyCalibration("Actar/TIME"+NPL::itoa(m_EventData->Get_PadNumber(i)),m_EventData->Get_Time(i)); - if (m_EventData->Get_Charge(i) > m_E_Threshold) { - m_PreTreatedData->SetCharge(m_EventData->Get_Charge(i)); - m_PreTreatedData->SetPadNumber(m_EventData->Get_PadNumber(i)); - m_PreTreatedData->SetRowNumber(m_EventData->Get_PadRow(i)); - m_PreTreatedData->SetColumnNumber(m_EventData->Get_PadColumn(i)); - m_PreTreatedData->SetTime(m_EventData->Get_Time(i)); - } + // This method typically applies thresholds and calibrations + // Might test for disabled channels for more complex detector + + // clear pre-treated object + ClearPreTreatedData(); + + CleanPads(); + + // instantiate CalibrationManager + static CalibrationManager* Cal = CalibrationManager::getInstance(); + + + unsigned int mysize = m_EventReduced->CoboAsad.size(); + + for (unsigned int it = 0; it < mysize ; ++it) { + int co=m_EventReduced->CoboAsad[it].globalchannelid>>11; + int as=(m_EventReduced->CoboAsad[it].globalchannelid - (co<<11))>>9; + int ag=(m_EventReduced->CoboAsad[it].globalchannelid - (co<<11)-(as<<9))>>7; + int ch=m_EventReduced->CoboAsad[it].globalchannelid - (co<<11)-(as<<9)-(ag<<7); + int where=co*NumberOfASAD*NumberOfAGET*NumberOfChannel + as*NumberOfAGET*NumberOfChannel + ag*NumberOfChannel + ch; + + if(co!=31){ + unsigned int vector_size = m_EventReduced->CoboAsad[it].peakheight.size(); + for(unsigned int hh=0; hh<vector_size; hh++){ + if(m_EventReduced->CoboAsad[it].peakheight[hh]>fQ_Threshold && m_EventReduced->CoboAsad[it].peaktime[hh]>fT_Threshold){ + if(GoodHit(TABLE[4][where],TABLE[5][where])){ + //if(Hit[TABLE[4][where]][TABLE[5][where]]<2){ + PadCharge.push_back(m_EventReduced->CoboAsad[it].peakheight[hh]); + PadX.push_back(TABLE[4][where]); + PadY.push_back(TABLE[5][where]); + PadZ.push_back(m_EventReduced->CoboAsad[it].peaktime[hh]); + + //} + } + } + } + } + else if(co==31){ + unsigned int vector_size = m_EventReduced->CoboAsad[it].peakheight.size(); + for(unsigned int hit=0;hit<vector_size;hit++){ + + Si_Number.push_back(m_EventReduced->CoboAsad[it].peaktime[hit]); + Si_E.push_back(m_EventReduced->CoboAsad[it].peakheight[hit]); + + int vxi_parameter = m_EventReduced->CoboAsad[it].peaktime[hit]; + if(Si_map[vxi_parameter]<21 && Si_map[vxi_parameter]>0){ + m_PreTreatedData->SetSiliconEnergy(m_EventReduced->CoboAsad[it].peakheight[hit]); + m_PreTreatedData->SetSiliconDetectorNumber(Si_map[vxi_parameter]); + } + } + } } - } +} +/////////////////////////////////////////////////////////////////////////// +bool TActarPhysics::GoodHit(int iX, int iY) +{ + bool bHit = true; + if(Hit[iX][iY]<2){ + if(Hit[iX+1][iY]>0 || Hit[iX+1][iY-1]>0 || Hit[iX+1][iY+1]>0){ + if(Hit[iX+2][iY]>0 || Hit[iX+2][iY-1]>0 || Hit[iX+2][iY+1]>0){ + bHit = true; + } + } + } + + return bHit; } + /////////////////////////////////////////////////////////////////////////// -void TActarPhysics::HoughTransform(vector<int> v1, vector<int> v2, vector<int> v3){ - for(unsigned int i=0; i<v1.size(); i++){ - for(int itheta=0; itheta<180; itheta++){ - HoughAngle.push_back(itheta); - double tmp= v1[i]*cos(itheta*NPUNITS::deg)+v2[i]*sin(itheta*NPUNITS::deg); - HoughRadius.push_back(tmp); +void TActarPhysics::CleanPads() +{ + unsigned int mysize = m_EventReduced->CoboAsad.size(); + + for(unsigned int it=0; it<mysize; it++){ + int co=m_EventReduced->CoboAsad[it].globalchannelid>>11; + int as=(m_EventReduced->CoboAsad[it].globalchannelid - (co<<11))>>9; + int ag=(m_EventReduced->CoboAsad[it].globalchannelid - (co<<11)-(as<<9))>>7; + int ch=m_EventReduced->CoboAsad[it].globalchannelid - (co<<11)-(as<<9)-(ag<<7); + int where=co*NumberOfASAD*NumberOfAGET*NumberOfChannel + as*NumberOfAGET*NumberOfChannel + ag*NumberOfChannel + ch; + + + if(co!=31){ + unsigned int vector_size = m_EventReduced->CoboAsad[it].peakheight.size(); + for(unsigned int hh=0; hh < vector_size; hh++){ + if(m_EventReduced->CoboAsad[it].peakheight[hh]>fQ_Threshold && m_EventReduced->CoboAsad[it].peaktime[hh]>fT_Threshold){ + Hit[TABLE[4][where]][TABLE[5][where]] += 1; + /* + m_PreTreatedData->SetCharge(m_EventReduced->CoboAsad[it].peakheight[hh]); + m_PreTreatedData->SetPadX(TABLE[4][where]); + m_PreTreatedData->SetPadY(TABLE[5][where]); + m_PreTreatedData->SetPadZ(m_EventReduced->CoboAsad[it].peaktime[hh]);*/ + } + } + } } - } } /////////////////////////////////////////////////////////////////////////// void TActarPhysics::ReadAnalysisConfig() { - bool ReadingStatus = false; - - // path to file - string FileName = "./configs/ConfigActar.dat"; - - // open analysis config file - ifstream AnalysisConfigFile; - AnalysisConfigFile.open(FileName.c_str()); - - if (!AnalysisConfigFile.is_open()) { - cout << " No ConfigActar.dat found: Default parameter loaded for Analayis " << FileName << endl; - return; - } - cout << " Loading user parameter for Analysis from ConfigActar.dat " << endl; - - // Save it in a TAsciiFile - TAsciiFile* asciiConfig = RootOutput::getInstance()->GetAsciiFileAnalysisConfig(); - asciiConfig->AppendLine("%%% ConfigActar.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 = "ConfigActar"; - 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; - } + // VXI ACTION FILE // + string VXI_FileName = "./configs/ACTION_Si_config.dat"; + ifstream VXIConfigFile; + VXIConfigFile.open(VXI_FileName.c_str()); + if(!VXIConfigFile.is_open()){ + cout << "No VXI ACTION FILE ./configs/ACTION_Si_config.dat found!" << endl; + return; + } + else{ + cout << "/// Using VXI ACTION FILE: " << VXI_FileName << " ///" << endl; + string token; + int vxi_param, si_nbr; + for(int i=0; i<20; i++){ + VXIConfigFile >> token >> vxi_param >> si_nbr; + Si_map[vxi_param] = si_nbr+1; + } + } + VXIConfigFile.close(); + + // Lookup table // + bool ReadingLookupTable = false; + string LT_FileName = "./configs/LT.dat"; + ifstream LTConfigFile; + LTConfigFile.open(LT_FileName.c_str()); + if(!LTConfigFile.is_open()){ + cout << "No Lookup Table in ./configs/LT.dat found!" << endl; + return; + } + else{ + cout << "/// Using LookupTable from: " << LT_FileName << " ///" << endl; + for(int i=0;i<NumberOfCobo*NumberOfASAD*NumberOfAGET*NumberOfChannel;i++){ + LTConfigFile >> TABLE[0][i] >> TABLE[1][i] >> TABLE[2][i] >> TABLE[3][i] >> TABLE[4][i] >> TABLE[5][i]; + } + ReadingLookupTable = true; + } + LTConfigFile.close(); + + + bool ReadingStatus = false; + + // ACTAR config file // + string FileName = "./configs/ConfigActar.dat"; + + // open analysis config file + ifstream AnalysisConfigFile; + AnalysisConfigFile.open(FileName.c_str()); + + if (!AnalysisConfigFile.is_open()) { + cout << " No ConfigActar.dat found: Default parameter loaded for Analayis " << FileName << endl; + return; + } + cout << "/// Loading user parameter for Analysis from ConfigActar.dat ///" << endl; + + // Save it in a TAsciiFile + TAsciiFile* asciiConfig = RootOutput::getInstance()->GetAsciiFileAnalysisConfig(); + asciiConfig->AppendLine("%%% ConfigActar.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 = "ConfigActar"; + if (LineBuffer.compare(0, name.length(), name) == 0){ + ReadingStatus = true; + cout << "**** ConfigActar found" << endl; + } + + // 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.compare(0,11,"RecoRansac=") == 0) { + AnalysisConfigFile >> DataBuffer; + fRecoRansac = atoi(DataBuffer.c_str()); + cout << "/// Reco using Ransac= " << " " << fRecoRansac << " ///" << endl; + } + + else if (whatToDo.compare(0,9,"RecoVisu=") == 0) { + AnalysisConfigFile >> DataBuffer; + fRecoVisu = atoi(DataBuffer.c_str()); + cout << "/// Visualisation= " << " " << fRecoVisu << " ///" << endl; + } + + else if (whatToDo.compare(0,14,"HIT_THRESHOLD=") == 0) { + AnalysisConfigFile >> DataBuffer; + fHitThreshold = atoi(DataBuffer.c_str()); + cout << "/// Hit Threshold= " << " " << fHitThreshold << " ///" << endl; + } + + else if (whatToDo.compare(0,12,"Q_THRESHOLD=") == 0) { + AnalysisConfigFile >> DataBuffer; + fQ_Threshold = atof(DataBuffer.c_str()); + cout << "/// Q Threshold= " << " " << fQ_Threshold << " ///" << endl; + } + + else if (whatToDo.compare(0,12,"T_THRESHOLD=") == 0) { + AnalysisConfigFile >> DataBuffer; + fT_Threshold = atof(DataBuffer.c_str()); + cout << "/// T Threshold= " << " " << fT_Threshold << " ///" << endl; + } + else if(whatToDo.compare(0,14,"NumberOfPadsX=")==0){ + AnalysisConfigFile >> DataBuffer; + fNumberOfPadsX = atoi(DataBuffer.c_str()); + //check_padsX=true; + cout << "/// Number Of Pads X= " << fNumberOfPadsX << " ///" << endl; + } + + else if(whatToDo.compare(0,14,"NumberOfPadsY=")==0){ + AnalysisConfigFile >> DataBuffer; + fNumberOfPadsY = atoi(DataBuffer.c_str()); + //check_padsY=true; + cout << "/// Number Of Pads Y= " << fNumberOfPadsY << " ///" << endl; + } + + else if(whatToDo.compare(0,9,"PadSizeX=")==0){ + AnalysisConfigFile >> DataBuffer; + fPadSizeX = atof(DataBuffer.c_str()); + //check_sizeX=true; + cout << "/// Pad Size X= " << fPadSizeX << " ///" << endl; + } + + else if(whatToDo.compare(0,9,"PadSizeY=")==0){ + AnalysisConfigFile >> DataBuffer; + fPadSizeY = atof(DataBuffer.c_str()); + //check_sizeY=true; + cout << "/// Pad Size Y= " << fPadSizeY << " ///" << endl; + } + + else if(whatToDo.compare(0,9,"Pressure=")==0){ + AnalysisConfigFile >> DataBuffer; + fPressure = atof(DataBuffer.c_str()); + //check_pressure=true; + cout << "/// Pressure= " << fPressure << " ///" << endl; + } + + else if(whatToDo.compare(0,14,"DriftVelocity=")==0){ + AnalysisConfigFile >> DataBuffer; + fDriftVelocity = atof(DataBuffer.c_str()); + //check_driftvelocity=true; + cout << "/// Drift Velocity= " << fDriftVelocity << " ///" << endl; + } + + else if(whatToDo.compare(0,4,"Gas=")==0){ + AnalysisConfigFile >> DataBuffer; + fGas = DataBuffer.c_str(); + //check_gas=true; + cout << "/// Gas Type= " << fGas << " ///" << endl; + } + + else { + ReadingStatus = false; + } + } + } + + if(fRecoRansac){ + m_Ransac = new NPL::Ransac(fNumberOfPadsX,fNumberOfPadsY,fRecoVisu); } - } } - +/////////////////////////////////////////////////////////////////////////// +void TActarPhysics::SetRansacParameter(string filename){ + if(fRecoRansac){ + m_Ransac->ReadParameterValue(filename); + } +} /////////////////////////////////////////////////////////////////////////// void TActarPhysics::Clear() { - PadNumber.clear(); - PadRow.clear(); - PadColumn.clear(); - PadCharge.clear(); - PadTime.clear(); - - HoughRadius.clear(); - HoughAngle.clear(); + PadX.clear(); + PadY.clear(); + PadZ.clear(); + PadCharge.clear(); + m_Track.clear(); + Si_Number.clear(); + Si_E.clear(); + + for(int i=0; i<fNumberOfPadsX; i++){ + for(int j=0; j<fNumberOfPadsY; j++){ + Hit[i][j] = 0; + } + } } /////////////////////////////////////////////////////////////////////////// void TActarPhysics::ReadConfiguration(NPL::InputParser parser) { - vector<NPL::InputBlock*> blocks = parser.GetAllBlocksWithToken("Actar"); - 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 << "//// Actar " << 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 << "//// Actar " << 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); + vector<NPL::InputBlock*> blocks = parser.GetAllBlocksWithToken("Actar"); + 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 << "//// Actar " << 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 << "//// Actar " << 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 TActarPhysics::InitSpectra() { - m_Spectra = new TActarSpectra(m_NumberOfDetectors); + m_Spectra = new TActarSpectra(m_NumberOfDetectors); } /////////////////////////////////////////////////////////////////////////// void TActarPhysics::FillSpectra() { - m_Spectra -> FillRawSpectra(m_EventData); - m_Spectra -> FillPreTreatedSpectra(m_PreTreatedData); - m_Spectra -> FillPhysicsSpectra(m_EventPhysics); + m_Spectra -> FillRawSpectra(m_EventData); + m_Spectra -> FillPreTreatedSpectra(m_PreTreatedData); + m_Spectra -> FillPhysicsSpectra(m_EventPhysics); } /////////////////////////////////////////////////////////////////////////// void TActarPhysics::CheckSpectra() { - m_Spectra->CheckSpectra(); + m_Spectra->CheckSpectra(); } /////////////////////////////////////////////////////////////////////////// void TActarPhysics::ClearSpectra() { - // To be done + // To be done } /////////////////////////////////////////////////////////////////////////// map< string , TH1*> TActarPhysics::GetSpectra() { - if(m_Spectra) - return m_Spectra->GetMapHisto(); - else{ - map< string , TH1*> empty; - return empty; - } + if(m_Spectra) + return m_Spectra->GetMapHisto(); + else{ + map< string , TH1*> empty; + return empty; + } } //////////////////////////////////////////////////////////////////////////////// vector<TCanvas*> TActarPhysics::GetCanvas() { - //if(m_Spectra) + //if(m_Spectra) //return m_Spectra->GetCanvas(); - //else{ - //vector<TCanvas*> empty; - //return empty; - //} - return vector<TCanvas*>(); + //else{ + vector<TCanvas*> empty; + return empty; + //} } /////////////////////////////////////////////////////////////////////////// void TActarPhysics::WriteSpectra() { - m_Spectra->WriteSpectra(); + m_Spectra->WriteSpectra(); } /////////////////////////////////////////////////////////////////////////// void TActarPhysics::AddParameterToCalibrationManager() { - CalibrationManager* Cal = CalibrationManager::getInstance(); - for (int i = 0; i < m_NumberOfDetectors; ++i) { - Cal->AddParameter("Actar", "D"+ NPL::itoa(i+1)+"_CHARGE","Actar_D"+ NPL::itoa(i+1)+"_CHARGE"); - Cal->AddParameter("Actar", "D"+ NPL::itoa(i+1)+"_TIME","Actar_D"+ NPL::itoa(i+1)+"_TIME"); - } + CalibrationManager* Cal = CalibrationManager::getInstance(); + for (int i = 0; i < m_NumberOfDetectors; ++i) { + Cal->AddParameter("Actar", "D"+ NPL::itoa(i+1)+"_CHARGE","Actar_D"+ NPL::itoa(i+1)+"_CHARGE"); + Cal->AddParameter("Actar", "D"+ NPL::itoa(i+1)+"_TIME","Actar_D"+ NPL::itoa(i+1)+"_TIME"); + } } +/////////////////////////////////////////////////////////////////////////// +/*void TActarPhysics::InitializeRootInputRaw() { + TChain* inputChain = RootInput::getInstance()->GetChain(); + inputChain->SetBranchStatus("Actar", true ); + inputChain->SetBranchAddress("Actar", &m_EventData ); +}*/ + /////////////////////////////////////////////////////////////////////////// void TActarPhysics::InitializeRootInputRaw() { - TChain* inputChain = RootInput::getInstance()->GetChain(); - inputChain->SetBranchStatus("Actar", true ); - inputChain->SetBranchAddress("Actar", &m_EventData ); + TChain* inputChain = RootInput::getInstance()->GetChain(); + inputChain->SetBranchStatus("data", true ); + inputChain->SetBranchStatus("ACTAR_TTree", true ); + inputChain->SetBranchAddress("data", &m_EventReduced ); } /////////////////////////////////////////////////////////////////////////// void TActarPhysics::InitializeRootInputPhysics() { - TChain* inputChain = RootInput::getInstance()->GetChain(); - inputChain->SetBranchAddress("Actar", &m_EventPhysics); + TChain* inputChain = RootInput::getInstance()->GetChain(); + inputChain->SetBranchAddress("Actar", &m_EventPhysics); } /////////////////////////////////////////////////////////////////////////// void TActarPhysics::InitializeRootOutput() { - TTree* outputTree = RootOutput::getInstance()->GetTree(); - outputTree->Branch("Actar", "TActarPhysics", &m_EventPhysics); + TTree* outputTree = RootOutput::getInstance()->GetTree(); + outputTree->Branch("Actar", "TActarPhysics", &m_EventPhysics); } @@ -354,7 +555,7 @@ void TActarPhysics::InitializeRootOutput() { // Construct Method to be pass to the DetectorFactory // //////////////////////////////////////////////////////////////////////////////// NPL::VDetector* TActarPhysics::Construct() { - return (NPL::VDetector*) new TActarPhysics(); + return (NPL::VDetector*) new TActarPhysics(); } @@ -363,13 +564,13 @@ NPL::VDetector* TActarPhysics::Construct() { // Registering the construct method to the factory // //////////////////////////////////////////////////////////////////////////////// extern "C"{ -class proxy_Actar{ - public: - proxy_Actar(){ - NPL::DetectorFactory::getInstance()->AddToken("Actar","Actar"); - NPL::DetectorFactory::getInstance()->AddDetector("Actar",TActarPhysics::Construct); - } -}; - -proxy_Actar p_Actar; + class proxy_Actar{ + public: + proxy_Actar(){ + NPL::DetectorFactory::getInstance()->AddToken("Actar","Actar"); + NPL::DetectorFactory::getInstance()->AddDetector("Actar",TActarPhysics::Construct); + } + }; + + proxy_Actar p_Actar; } diff --git a/NPLib/Detectors/Actar/TActarPhysics.h b/NPLib/Detectors/Actar/TActarPhysics.h index 6240921b0..ab740fa95 100644 --- a/NPLib/Detectors/Actar/TActarPhysics.h +++ b/NPLib/Detectors/Actar/TActarPhysics.h @@ -8,7 +8,7 @@ *****************************************************************************/ /***************************************************************************** - * Original Author: Pierre Morfouace contact address: morfouac@nscl.msu.edu * + * Original Author: Pierre Morfouace contact address: morfouace@ganil.fr * * * * Creation Date : September 2017 * * Last update : * @@ -33,157 +33,203 @@ using namespace std; #include "TH1.h" #include "TCanvas.h" #include "TVector3.h" + // NPTool headers +#include "MEventReduced.h" #include "TActarData.h" #include "TActarSpectra.h" #include "NPCalibrationManager.h" #include "NPVDetector.h" #include "NPInputParser.h" -// forward declaration -class TActarSpectra; +#include "NPTrack.h" +#include "NPRansac.h" +#define NumberOfCobo 16 +#define NumberOfASAD 4 +#define NumberOfAGET 4 +#define NumberOfChannel 68 +class TActarSpectra; class TActarPhysics : public TObject, public NPL::VDetector { - ////////////////////////////////////////////////////////////// - // constructor and destructor - public: + ////////////////////////////////////////////////////////////// + // constructor and destructor +public: TActarPhysics(); ~TActarPhysics() {}; - - - ////////////////////////////////////////////////////////////// - // Inherited from TObject and overriden to avoid warnings - public: + + + ////////////////////////////////////////////////////////////// + // 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> PadNumber; - vector<int> PadRow; - vector<int> PadColumn; - vector<int> PadTime; + + + ////////////////////////////////////////////////////////////// + // data obtained after BuildPhysicalEvent() and stored in + // output ROOT file +public: + vector<int> PadX; + vector<int> PadY; + vector<double> PadZ; vector<double> PadCharge; - - vector<double> HoughRadius; - vector<double> HoughAngle; - - /// 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: + vector<double> Si_E; + vector<int> Si_Number; + int TrackMult; + + /// 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); + +public: + int GetTrackMult() {return m_Track.size();} + vector<NPL::Track> GetTracks() {return m_Track;} + + + ////////////////////////////////////////////////////////////// + // 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 TActarSpectra class // instantiate the TActarSpectra 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 Actar array - public: + + + ////////////////////////////////////////////////////////////// + // specific methods to Actar 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(); - + + void CleanPads(); + + bool GoodHit(int iX, int iY); + // give and external TActarData object to TActarPhysics. // needed for online analysis for example void SetRawDataPointer(TActarData* rawDataPointer) {m_EventData = rawDataPointer;} - - void HoughTransform(vector<int> v1, vector<int> v2, vector<int> v3); - - // objects are not written in the TTree - private: + + // objects are not written in the TTree +private: TActarData* m_EventData; //! + MEventReduced* m_EventReduced; //! TActarData* m_PreTreatedData; //! TActarPhysics* m_EventPhysics; //! - - // getters for raw and pre-treated data object - public: + NPL::Ransac* m_Ransac; //! + vector<NPL::Track> m_Track; //! + + // getters for raw and pre-treated data object +public: TActarData* GetRawData() const {return m_EventData;} TActarData* GetPreTreatedData() const {return m_PreTreatedData;} - - // parameters used in the analysis - private: + + double GetDriftVelocity() {return fDriftVelocity;} + double GetPadSizeX() {return fPadSizeX;} + double GetPadSizeY() {return fPadSizeY;} + int GetNumberOfPadsX() {return fNumberOfPadsX;} + int GetNumberOfPadsY() {return fNumberOfPadsY;} + double GetPRessure() {return fPressure;} + string GetGasName() {return fGas;} + + // parameters used in the analysis +private: // thresholds - double m_E_RAW_Threshold; //! - double m_E_Threshold; //! - - // number of detectors - private: + int fHitThreshold; //! + int fQ_Threshold; //! + int fT_Threshold; //! + int fNumberOfPadsX; //! + int fNumberOfPadsY; //! + double fPadSizeX; //! + double fPadSizeY; //! + double fDriftVelocity; //! + double fPressure; //! + string fGas; //! + bool fRecoRansac; //! + bool fRecoVisu; //! + map<int, int> Si_map; //! + + int TABLE[6][NumberOfCobo*NumberOfASAD*NumberOfAGET*NumberOfChannel]; //! + int Hit[128][128]; //! + + + // number of detectors +private: int m_NumberOfDetectors; //! - - // spectra class - private: - TActarSpectra* m_Spectra; // ! - - // spectra getter - public: + + // spectra class +private: + TActarSpectra* m_Spectra; //! + + //spme getters and setters +public: + void SetRansacParameter(string filename); + NPL::Ransac* GetRansacObject() {return m_Ransac;} + bool GetRansacStatus() {return fRecoRansac;} + + + // spectra getter +public: map<string, TH1*> GetSpectra(); vector<TCanvas*> GetCanvas(); - - // Static constructor to be passed to the Detector Factory - public: + + // Static constructor to be passed to the Detector Factory +public: static NPL::VDetector* Construct(); - + ClassDef(TActarPhysics,1) // ActarPhysics structure }; #endif diff --git a/NPLib/Detectors/Actar/TActarSpectra.cxx b/NPLib/Detectors/Actar/TActarSpectra.cxx index f37527d1a..31e3cd0b0 100644 --- a/NPLib/Detectors/Actar/TActarSpectra.cxx +++ b/NPLib/Detectors/Actar/TActarSpectra.cxx @@ -112,21 +112,21 @@ void TActarSpectra::FillRawSpectra(TActarData* RawData) { static string family; // Charge - unsigned int sizeE = RawData->GetMultCharge(); + unsigned int sizeE = RawData->GetPadMult(); for (unsigned int i = 0; i < sizeE; i++) { - name = "Actar"+NPL::itoa(RawData->Get_PadNumber(i))+"_CHARGE_RAW"; + name = "Actar"+NPL::itoa(RawData->GetPadNumber(i))+"_CHARGE_RAW"; family = "Actar/RAW"; - //GetHisto(family,name) -> Fill(RawData->Get_Charge(i)); + //GetHisto(family,name) -> Fill(RawData->GetPadCharge(i)); } // Time - unsigned int sizeT = RawData->GetMultCharge(); + unsigned int sizeT = RawData->GetPadMult(); for (unsigned int i = 0; i < sizeT; i++) { - name = "Actar"+NPL::itoa(RawData->Get_PadNumber(i))+"_TIME_RAW"; + name = "Actar"+NPL::itoa(RawData->GetPadNumber(i))+"_TIME_RAW"; family = "Actar/RAW"; - //GetHisto(family,name) -> Fill(RawData->Get_Time(i)); + //GetHisto(family,name) -> Fill(RawData->GetPadZ(i)); } } @@ -138,21 +138,21 @@ void TActarSpectra::FillPreTreatedSpectra(TActarData* PreTreatedData) { static string family; // Energy - unsigned int sizeE = PreTreatedData->GetMultCharge(); + unsigned int sizeE = PreTreatedData->GetPadMult(); for (unsigned int i = 0; i < sizeE; i++) { - name = "Actar"+NPL::itoa(PreTreatedData->Get_PadNumber(i))+"_ENERGY_CAL"; + name = "Actar"+NPL::itoa(PreTreatedData->GetPadNumber(i))+"_ENERGY_CAL"; family = "Actar/CAL"; - //GetHisto(family,name) -> Fill(PreTreatedData->Get_Charge(i)); + //GetHisto(family,name) -> Fill(PreTreatedData->GetPadCharge(i)); } // Time - unsigned int sizeT = PreTreatedData->GetMultCharge(); + unsigned int sizeT = PreTreatedData->GetPadMult(); for (unsigned int i = 0; i < sizeT; i++) { - name = "Actar"+NPL::itoa(PreTreatedData->Get_PadNumber(i))+"_TIME_CAL"; + name = "Actar"+NPL::itoa(PreTreatedData->GetPadNumber(i))+"_TIME_CAL"; family = "Actar/CAL"; - //GetHisto(family,name) -> Fill(PreTreatedData->Get_Time(i)); + //GetHisto(family,name) -> Fill(PreTreatedData->GetPadZ(i)); } } diff --git a/NPLib/TrackReconstruction/CMakeLists.txt b/NPLib/TrackReconstruction/CMakeLists.txt new file mode 100644 index 000000000..4d17e167c --- /dev/null +++ b/NPLib/TrackReconstruction/CMakeLists.txt @@ -0,0 +1,6 @@ +add_custom_command(OUTPUT NPRansacDict.cxx COMMAND ../scripts/build_dict.sh NPRansac.h NPRansacDict.cxx NPRansac.rootmap libNPTrackReconstruction.so NPTrackReconstructionLinkDef.h DEPENDS NPRansac.h) + +add_library(NPTrackReconstruction SHARED NPRansac.cxx NPTrack.cxx NPRansacDict.cxx) +target_link_libraries(NPTrackReconstruction ${ROOT_LIBRARIES} NPCore) + +install(FILES NPRansac.h NPTrack.h DESTINATION ${CMAKE_INCLUDE_OUTPUT_DIRECTORY}) diff --git a/NPLib/TrackReconstruction/NPRansac.cxx b/NPLib/TrackReconstruction/NPRansac.cxx new file mode 100644 index 000000000..ec0d36bfb --- /dev/null +++ b/NPLib/TrackReconstruction/NPRansac.cxx @@ -0,0 +1,774 @@ +/***************************************************************************** + * 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 : Pierre MORFOUACE contact address: morfouace@ganil.fr * + * * + * Creation Date : April 2018 * + * Last update : April 2018 * + *---------------------------------------------------------------------------* + * Decription: * + * This class deal with finding all the track event by event * + *****************************************************************************/ + +#include "NPRansac.h" +using namespace NPL; + +using namespace std; + +ClassImp(Ransac) + +///////////////////////////////////////////////// +Ransac::Ransac() +{ + fRANSACMaxIteration = 1000; + fRANSACThreshold = 30;//100; + fRANSACPointThreshold = 0.04;//0.07; + fRANSACChargeThreshold = 0.04;//0.07; + fRANSACDistance = 11;//7; + fMAXBarycenterDistance = 10; + fAngleMax = 2;//degree + fMergeWithBarycenter = true; + fMergeWithScalarProduct = false; + + fNumberOfPadsX = 128; + fNumberOfPadsY = 128; +} + +///////////////////////////////////////////////// +Ransac::Ransac(int NumberOfPadsX, int NumberOfPadsY, bool Visu) +{ + fRANSACMaxIteration = 1000; + fRANSACThreshold = 60;//100; + fRANSACPointThreshold = 0.04;//0.07; + fRANSACChargeThreshold = 0.04;//0.07; + fRANSACDistance = 11;//7; + + fNumberOfPadsX = NumberOfPadsX; + fNumberOfPadsY = NumberOfPadsY; + fVisu = Visu; + //fNumberOfTracksMax = 10; + + if(fVisu==1){ + m_ServerSocket = new TServerSocket(9092,true,100); + //pl = new TGraph2D(); + if(!m_ServerSocket->IsValid()){ + cout << endl; + cout << "/// ServerSocket invalid! ///" << endl; + exit(1); + } + cout << endl; + cout << "/// ServerSocket valid ///" << endl; + m_ServerSocket->SetCompressionSettings(1); + + // Add server socket to monitor so we are notified when a client needs to be + // accepted + m_Monitor = new TMonitor(); + m_Monitor->Add(m_ServerSocket,TMonitor::kRead|TMonitor::kWrite); + // Create a list to contain all client connections + m_Sockets = new TList; + + // Create a list to contain all client connections + m_Histo = new TList; + + } +} + + +////////////////////////////////////////////////// +Ransac::~Ransac() +{ + for(unsigned int i=0; i<vline.size(); i++){ + delete vline[i]; + } +} + +////////////////////////////////////////////////// +void Ransac::ReadParameterValue(string filename) +{ + bool ReadingStatus = false; + + ifstream RansacParamFile; + RansacParamFile.open(filename.c_str()); + + if(!RansacParamFile.is_open()){ + cout << "No Paramter File found for Ransac parameters" << endl; + cout << "Using the default parameter:" << endl; + cout << "RANSAC MaxIteration= " << fRANSACMaxIteration << endl; + cout << "RANSAC Threshold=" << fRANSACThreshold << endl; + cout << "RANSAC ChargeThreshold= " << fRANSACChargeThreshold << endl; + cout << "RANSAC Distance= " << fRANSACDistance << endl; + cout << "RANSAC PointThreshold= " << fRANSACPointThreshold << endl; + cout << "MAX Barycenter Distance= " << fMAXBarycenterDistance << endl; + cout << "Angle Max to merge tracks= " << fAngleMax << endl; + cout << "Merging Tracks using the barycenter= " << fMergeWithBarycenter << endl; + cout << "Merging Tracks using the scalar product= " << fMergeWithScalarProduct << endl; + } + else{ + string LineBuffer, whatToDo, DataBuffer; + while(!RansacParamFile.eof()){ + getline(RansacParamFile,LineBuffer); + string name = "ConfigRansac"; + if(LineBuffer.compare(0, name.length(), name) == 0){ + cout << endl; + cout << "**** ConfigRansac found" << endl; + ReadingStatus = true; + } + while(ReadingStatus){ + whatToDo=""; + RansacParamFile >> whatToDo; + // Search for comment symbol (%) + if (whatToDo.compare(0, 1, "%") == 0) { + RansacParamFile.ignore(numeric_limits<streamsize>::max(), '\n' ); + } + else if (whatToDo.compare(0,19,"RANSACMaxIteration=") == 0) { + RansacParamFile >> DataBuffer; + fRANSACMaxIteration = atoi(DataBuffer.c_str()); + cout << "/// RANSAC MaxIteration= " << " " << fRANSACMaxIteration << " ///" << endl; + } + else if (whatToDo.compare(0,15,"RANSACDistance=") == 0) { + RansacParamFile >> DataBuffer; + fRANSACDistance = atoi(DataBuffer.c_str()); + cout << "/// RANSAC Distance= " << " " << fRANSACDistance << " ///" << endl; + } + else if (whatToDo.compare(0,22,"RANSACChargeThreshold=") == 0) { + RansacParamFile >> DataBuffer; + fRANSACChargeThreshold = atof(DataBuffer.c_str()); + cout << "/// RANSAC ChargeThreshold= " << " " << fRANSACChargeThreshold << " ///" << endl; + } + else if (whatToDo.compare(0,21,"RANSACPointThreshold=") == 0) { + RansacParamFile >> DataBuffer; + fRANSACPointThreshold = atof(DataBuffer.c_str()); + cout << "/// RANSAC PointThreshold= " << " " << fRANSACPointThreshold << " ///" << endl; + } + else if (whatToDo.compare(0,16,"RANSACThreshold=") == 0) { + RansacParamFile >> DataBuffer; + fRANSACThreshold = atoi(DataBuffer.c_str()); + cout << "/// RANSAC Threshold= " << " " << fRANSACThreshold << " ///" << endl; + } + else if (whatToDo.compare(0,22,"MAXBarycenterDistance=") == 0) { + RansacParamFile >> DataBuffer; + fMAXBarycenterDistance = atoi(DataBuffer.c_str()); + cout << "/// Max Barycenter Distance= " << " " << fMAXBarycenterDistance << " ///" << endl; + } + else if (whatToDo.compare(0,16,"AngleMaxToMerge=") == 0) { + RansacParamFile >> DataBuffer; + fAngleMax = atoi(DataBuffer.c_str()); + cout << "/// Angle Max to merge tracks= " << " " << fAngleMax << " ///" << endl; + } + else if (whatToDo.compare(0,20,"MergeWithBarycenter=") == 0) { + RansacParamFile >> DataBuffer; + fMergeWithBarycenter = atoi(DataBuffer.c_str()); + cout << "/// Merging Tracks using the barycenter= " << " " << fMergeWithBarycenter << " ///" << endl; + } + else if (whatToDo.compare(0,23,"MergeWithScalarProduct=") == 0) { + RansacParamFile >> DataBuffer; + fMergeWithScalarProduct = atoi(DataBuffer.c_str()); + cout << "/// Merging Tracks using the scalar product= " << " " << fMergeWithScalarProduct << " ///" << endl; + } + else{ + ReadingStatus = false; + } + } + } + } +} + +////////////////////////////////////////////////// +void Ransac::Init(vector<int> v1, vector<int> v2, vector<double> v3, vector<double> v4) +{ + Reset(); + + vX = v1; + vY = v2; + vZ = v3; + vQ = v4; + + fOriginalCloudSize = vX.size(); + double TotalCharge=0; + for(unsigned int i=0; i< vQ.size(); i++){ + TotalCharge += vQ[i]; + } + fTotalCharge = TotalCharge; + +} + +////////////////////////////////////////////////// +vector<NPL::Track> Ransac::SimpleRansac() +{ + if(fVisu==1){ + m_Histo->Clear(); + } + + TRandom* Rand=new TRandom(); + double RemainingCharge = fTotalCharge; + /*cout << "/// Original total charge= " << fTotalCharge << endl; + cout << "/// Charge Threshold= " << fTotalCharge*fRANSACChargeThreshold << endl; + cout << "/// vX.size()= " << vX.size() << endl; + cout << "/// Point Threshold= " << fOriginalCloudSize*fRANSACPointThreshold << endl;*/ + + int aa=0; + //while(vX.size() > fOriginalCloudSize*fRANSACPointThreshold){ + //while(RemainingCharge > fTotalCharge*fRANSACChargeThreshold){ + while(RemainingCharge > fTotalCharge*fRANSACChargeThreshold && vX.size() > fOriginalCloudSize*fRANSACPointThreshold){ + aa++; + + double minErr=1E20; + trackX.clear(); + trackY.clear(); + trackZ.clear(); + trackQ.clear(); + + TVector3 V1, V2; + std::vector<int> inliners; + inliners.clear(); + + fRANSACMaxIteration = 2.0*vX.size(); + for(int i=0;i<fRANSACMaxIteration;i++){ + int vXsize = vX.size(); + int p1=(int)(Rand->Uniform(0,vXsize)); + int p2; + do p2=(int)(Rand->Uniform(0,vXsize)); + while(p2==p1); + + TVector3 Vu; + Vu.SetXYZ(vX[p2]-vX[p1],vY[p2]-vY[p1],vZ[p2]-vZ[p1]); + + std::vector<int> alsoin; + alsoin.clear(); + for(int p=0;p<vXsize;p++){ + if(p!=p1 && p!=p2 && vQ[p]){ + TVector3 Va; + Va.SetXYZ(vX[p2]-vX[p],vY[p2]-vY[p],vZ[p2]-vZ[p]); + TVector3 VaCVu=Va.Cross(Vu); + + if(VaCVu.Mag()/Vu.Mag()<fRANSACDistance){ + alsoin.push_back(p); + } + } + } + //cout << "****** " << vX.size() << " / " << alsoin.size() << endl; + + if(alsoin.size()>fRANSACThreshold){ + TVector3 v1, v2; + double chi2=Fit3D(vX,vY,vZ,vQ,alsoin,v1,v2); + if(chi2<minErr){ + minErr=chi2; + V1=v1; + V2=v2; + inliners=alsoin; + } + } + } + + if(inliners.size()==0) break; + //cout << "iteration " << aa << ": with also inliners: " << inliners.size() << endl; + + TVector3 Vdir = TVector3(V2.x()-V1.x(),V2.y()-V1.y(),V2.z()-V1.z()); + Vdir = Vdir.Unit(); + + NPL::Track myTrack = NPL::Track(); + + myTrack.Xm=V1.x(); + myTrack.Ym=V1.y(); + myTrack.Zm=V1.z(); + + myTrack.Xh=V2.x(); + myTrack.Yh=V2.y(); + myTrack.Zh=V2.z(); + + + + int TrackNumber = vTrack.size(); + TString TrackName = Form("Track%d",TrackNumber); + + int inliner_size = inliners.size(); + for(int p=0; p<inliner_size; p++){ + trackX.push_back(vX[inliners[p]]); + trackY.push_back(vY[inliners[p]]); + trackZ.push_back(vZ[inliners[p]]); + trackQ.push_back(vQ[inliners[p]]); + } + + myTrack.SetXPoints(trackX); + myTrack.SetYPoints(trackY); + myTrack.SetZPoints(trackZ); + myTrack.SetQPoints(trackQ); + + vTrack.push_back(myTrack); + + for(int i=inliner_size-1 ; i>=0 ; i--){ + vQ.erase(vQ.begin()+inliners[i]); + vX.erase(vX.begin()+inliners[i]); + vY.erase(vY.begin()+inliners[i]); + vZ.erase(vZ.begin()+inliners[i]); + } + + RemainingCharge = 0; + for(unsigned int i =0; i<vQ.size(); i++){ + RemainingCharge += vQ[i]; + } + //cout << "/// RemainingCharge= " << RemainingCharge << endl; + //cout << "////****** " << vX.size() << " / " << fOriginalCloudSize*fRANSACPointThreshold << endl; + //cout << "////****** " << RemainingCharge << " / " << fTotalCharge*fRANSACChargeThreshold << endl; + } + //cout << " //// Number of Tracks found " << vTrack.size() << " ////" << endl; + + if(fMergeWithBarycenter) DoMerge("barycenter"); + if(fMergeWithScalarProduct) DoMerge("scalar"); + + if(fVisu==1){ + int track_size = vTrack.size(); + for(int t=0; t<track_size; t++){ + h3D = new TGraph2D(); + for(int i=0; i<vTrack[t].GetXPoints().size(); i++){ + h3D->SetPoint(i, vTrack[t].GetXPoints()[i], vTrack[t].GetYPoints()[i], vTrack[t].GetZPoints()[i]); + } + m_Histo->Add(h3D); + + pl = new TGraph2D(); + + TVector3 Vdir = TVector3(vTrack[t].Xh-vTrack[t].Xm, vTrack[t].Yh-vTrack[t].Ym, vTrack[t].Zh-vTrack[t].Zm); + Vdir = Vdir.Unit(); + + //pl->SetName(TrackName); + pl->SetPoint(0,vTrack[t].Xm, vTrack[t].Ym, vTrack[t].Zm); + pl->SetPoint(1,vTrack[t].Xh, vTrack[t].Yh, vTrack[t].Zh); + pl->SetPoint(2,vTrack[t].Xm + 10*Vdir.x(), vTrack[t].Ym + 10*Vdir.y(), (vTrack[t].Zm + 10*Vdir.z())); + pl->SetPoint(3,vTrack[t].Xm + 100*Vdir.x(), vTrack[t].Ym + 100*Vdir.y(), (vTrack[t].Zm + 100*Vdir.z())); + pl->SetPoint(4,vTrack[t].Xm - 100*Vdir.x(), vTrack[t].Ym - 100*Vdir.y(), (vTrack[t].Zm - 100*Vdir.z())); + pl->SetLineColor(2); + pl->SetMarkerColor(2); + pl->SetMarkerStyle(8); + pl->SetMarkerSize(1); + pl->SetLineWidth(2); + m_Histo->Add(pl); + } + } + + + + if(fVisu && vTrack.size()>1 && vTrack.size()<4){ + TSocket* s = NULL; + char request[64]; + if(m_ServerSocket && m_Monitor){ + + m_Monitor->ResetInterrupt(); + TList readClients; + if((m_Monitor->Select(&readClients, NULL, 10)) > 0){ + s = (TSocket*) readClients.Last(); + readClients.RemoveLast(); + } + } + + if(s){ + if (s->IsA() == TServerSocket::Class()) { + // accept new connection from spy + TSocket* socket = ((TServerSocket*)s)->Accept(); + m_Monitor->Add(socket,TMonitor::kRead|TMonitor::kWrite); + m_Sockets->Add(socket); + cout << "Client Connected" << endl; + //NPL::SendInformation("NPL::SpectraServer","Accepted new client connection"); + } + else{ + // we only get string based requests from the spy + char request[64]; + if (s->Recv(request, sizeof(request)) <= 0) { + m_Monitor->Remove(s); + m_Sockets->Remove(s); + delete s; + //return; + } + // send requested object back + static TMessage answer(kMESS_OBJECT); + answer.Reset(); + + if (!strcmp(request, "RequestHisto")){ + answer.WriteObject(m_Histo); + s->Send(answer); + } + + else // answer nothing + s->Send(answer); + } + } + } + + return vTrack; +} + +////////////////////////////////////////////////// +bool Ransac::CompareTracksWithBarycenter(NPL::Track track1, NPL::Track track2) +{ + bool ToBeMerged = false; + + TVector3 bar1 = track1.GetPointBarycenter(); + TVector3 bar2 = track2.GetPointBarycenter(); + double Y1 = bar1.Y(); + double Z1 = bar1.Z(); + double Y2 = bar2.Y(); + double Z2 = bar2.Z(); + + double Distance = sqrt(pow(Y2-Y1,2) + pow(Z2-Z1,2)); + + if(Distance<fMAXBarycenterDistance) ToBeMerged=true; + + return ToBeMerged; +} + +////////////////////////////////////////////////// +bool Ransac::CompareTracksWithScalarProduct(NPL::Track track1, NPL::Track track2) +{ + bool ToBeMerged = false; + + TVector3 v1 = TVector3(track1.Xh-track1.Xm, track1.Zh-track1.Zm, track1.Zh-track1.Zm); + TVector3 v2 = TVector3(track2.Xh-track2.Xm, track2.Zh-track2.Zm, track2.Zh-track2.Zm); + + TVector3 v1_unit = v1.Unit(); + TVector3 v2_unit = v2.Unit(); + + double ScalarProduct = v1_unit.Dot(v2_unit); + + if(abs(ScalarProduct)>cos(fAngleMax*TMath::Pi()/180)) ToBeMerged=true; + + return ToBeMerged; +} + +////////////////////////////////////////////////// +NPL::Track Ransac::MergeTracks(vector<NPL::Track> tracks) +{ + NPL::Track newTrack = NPL::Track(); + vector<int> newTrackX, newTrackY, newTrackZ, newTrackQ; + + double X1=0; double Y1=0; double Z1=0; + double X2=0; double Y2=0; double Z2=0; + + for(int j=0; j<tracks.size(); j++){ + X1 += tracks[j].Xm; + Y1 += tracks[j].Ym; + Z1 += tracks[j].Zm; + + X2 += tracks[j].Xh; + Y2 += tracks[j].Yh; + Z2 += tracks[j].Zh; + + for(int k=0; k<tracks[j].GetXPoints().size(); k++){ + newTrackX.push_back(tracks[j].GetXPoints()[k]); + newTrackY.push_back(tracks[j].GetYPoints()[k]); + newTrackZ.push_back(tracks[j].GetZPoints()[k]); + } + + } + X1 = X1/tracks.size(); + Y1 = Y1/tracks.size(); + Z1 = Z1/tracks.size(); + X2 = X2/tracks.size(); + Y2 = Y2/tracks.size(); + Z2 = Z2/tracks.size(); + + newTrack.Xm=X1; + newTrack.Ym=Y1; + newTrack.Zm=Z1; + + newTrack.Xh=X2; + newTrack.Yh=Y2; + newTrack.Zh=Z2; + + newTrack.SetXPoints(newTrackX); + newTrack.SetYPoints(newTrackY); + newTrack.SetZPoints(newTrackZ); + + return newTrack; +} + +////////////////////////////////////////////////// +void Ransac::DoMerge(string method) +{ + vector<NPL::Track> vTrack_new; + vector<NPL::Track> vTrackToMerge; + vector<NPL::Track> vTrack_temp; + vTrack_temp = vTrack; + NPL::Track newTrack = NPL::Track(); + + int size = vTrack.size(); + vector<int> id_track; + for(int i=0; i<size-1; i++){ + int NumberOfTrackToBeMergedWith=0; + vTrackToMerge.clear(); + + for(int j=i+1; j<size; j++){ + if(find(id_track.begin(),id_track.end(), j) == id_track.end()){ + if(method=="scalar") { + if( CompareTracksWithScalarProduct(vTrack[i],vTrack[j]) ){ + NumberOfTrackToBeMergedWith++; + id_track.push_back(j); + vTrackToMerge.push_back(vTrack[j]); + } + } + else if(method=="barycenter") { + if( CompareTracksWithBarycenter(vTrack[i],vTrack[j]) ){ + NumberOfTrackToBeMergedWith++; + id_track.push_back(j); + vTrackToMerge.push_back(vTrack[j]); + } + } + else cout << "Method for merging not known: Problem with token!" << endl; + } + } + if(NumberOfTrackToBeMergedWith>0){ + if(find(id_track.begin(),id_track.end(), i) == id_track.end()) id_track.push_back(i); + vTrackToMerge.push_back(vTrack[i]); + + newTrack = MergeTracks(vTrackToMerge); + + vTrack_new.push_back(newTrack); + } + } + + std::sort(id_track.begin(), id_track.end()); + for(int p=id_track.size()-1; p>=0; p--){ + vTrack_temp.erase(vTrack_temp.begin()+id_track[p]); + } + + for(int p=0; p<vTrack_temp.size(); p++){ + vTrack_new.push_back(vTrack_temp[p]); + } + + vTrack.clear(); + vTrack = vTrack_new; +} + + +////////////////////////////////////////////////// +/*void Ransac::CheckTracks() +{ + vector<NPL::Track> vTrack_temp; + vTrack_temp = vTrack; + + int size = vTrack.size(); + vector<double> Ybar; + vector<double> Zbar; + + Ybar.clear(); + Zbar.clear(); + for(int i=0; i<size; i++){ + TVector3 bar = vTrack[i].GetPointBarycenter(); + Ybar.push_back(bar.Y()); + Zbar.push_back(bar.Z()); + } + + vector<double> Distance; + vector<int> id_i, id_j; + for(int i=0; i<size-1; i++){ + for(int j=i+1; j<size; j++){ + id_i.push_back(i); + id_j.push_back(j); + Distance.push_back(sqrt(pow(Ybar[i]-Ybar[j],2) + pow(Zbar[i]-Zbar[j],2))); + } + } + + vector<int> removed_id; + for(int c=0; c<Distance.size(); c++){ + if(Distance[c]<fMAXBarycenterDistance){ + if(find(removed_id.begin(),removed_id.end(), id_i[c]) == removed_id.end()) removed_id.push_back(id_i[c]); + if(find(removed_id.begin(),removed_id.end(), id_j[c]) == removed_id.end()) removed_id.push_back(id_j[c]); + } + } + + std::sort (removed_id.begin(), removed_id.end()); + for(int j=removed_id.size()-1; j>=0; j--){ + vTrack.erase(vTrack.begin()+removed_id[j]); + } + + + double X1=0; double Y1=0; double Z1=0; + double X2=0; double Y2=0; double Z2=0; + + NPL::Track newTrack = NPL::Track(); + vector<int> newTrackX, newTrackY, newTrackZ, newTrackQ; + + if(removed_id.size()>0){ + for(int j=0; j<removed_id.size(); j++){ + X1 += vTrack_temp[removed_id[j]].Xm; + Y1 += vTrack_temp[removed_id[j]].Ym; + Z1 += vTrack_temp[removed_id[j]].Zm; + + X2 += vTrack_temp[removed_id[j]].Xh; + Y2 += vTrack_temp[removed_id[j]].Yh; + Z2 += vTrack_temp[removed_id[j]].Zh; + + for(int k=0; k<vTrack_temp[removed_id[j]].GetXPoints().size(); k++){ + newTrackX.push_back(vTrack_temp[removed_id[j]].GetXPoints()[k]); + newTrackY.push_back(vTrack_temp[removed_id[j]].GetYPoints()[k]); + newTrackZ.push_back(vTrack_temp[removed_id[j]].GetZPoints()[k]); + } + + } + X1 = X1/removed_id.size(); + Y1 = Y1/removed_id.size(); + Z1 = Z1/removed_id.size(); + X2 = X2/removed_id.size(); + Y2 = Y2/removed_id.size(); + Z2 = Z2/removed_id.size(); + + newTrack.Xm=X1; + newTrack.Ym=Y1; + newTrack.Zm=Z1; + + newTrack.Xh=X2; + newTrack.Yh=Y2; + newTrack.Zh=Z2; + + newTrack.SetXPoints(newTrackX); + newTrack.SetYPoints(newTrackY); + newTrack.SetZPoints(newTrackZ); + + vTrack.push_back(newTrack); + } +}*/ + +////////////////////////////////////////////////// +vector<double> Ransac::GetChargeOfTracks() +{ + return vTrackCharge; +} + +////////////////////////////////////////////////// +vector<double> Ransac::GetTrackLength(double PadSizeX, double PadSizeY, double DriftVelocity) +{ + vector<double> length; + double Ymin, Ymax; + double Zmin, Zmax; + double Xmin = 240; + double Xmax = 256; + + for(unsigned int i=0; i<vTrack.size(); i++){ + double xh = vTrack[i].GetXh()*PadSizeX; + double xm = vTrack[i].GetXm()*PadSizeX; + double yh = vTrack[i].GetYh()*PadSizeY; + double ym = vTrack[i].GetYm()*PadSizeY; + double zh = vTrack[i].GetZh()*DriftVelocity; + double zm = vTrack[i].GetZm()*DriftVelocity; + + Ymin = yh + (ym - yh)*(Xmin-xh)/(xm-xh); + Ymax = yh + (ym - yh)*(Xmax-xh)/(xm-xh); + + Zmin = zh + (zm - zh)*(Xmin-xh)/(xm-xh); + Zmax = zh + (zm - zh)*(Xmax-xh)/(xm-xh); + + length.push_back(sqrt( pow(Xmax-Xmin,2) + pow(Ymax-Ymin,2) + pow(Zmax-Zmin,2) )); + } + + return length; +} + + +////////////////////////////////////////////////// +void Ransac::Reset() +{ + vline.clear(); + vX.clear(); + vY.clear(); + vZ.clear(); + vQ.clear(); + vTrack.clear(); + vTrackCharge.clear(); +} + +////////////////////////////////////////////////// +double Ransac::Fit3D(vector<int> X, vector<int> Y, vector<double> Z, vector<double> Charge, vector<int> inliners, TVector3& V1, TVector3& V2) +{ + // adapted from: http://fr.scribd.com/doc/31477970/Regressions-et-trajectoires-3D + + int R, C; + double Q; + double Xm,Ym,Zm; + double Xh,Yh,Zh; + double a,b; + double Sxx,Sxy,Syy,Sxz,Szz,Syz; + double theta; + double K11,K22,K12,K10,K01,K00; + double c0,c1,c2; + double p,q,r,dm2; + double rho,phi; + + Q=Xm=Ym=Zm=0.; + double total_charge=0; + Sxx=Syy=Szz=Sxy=Sxz=Syz=0.; + + for (auto i : inliners) + { + if(X[i]>119)total_charge+=Charge[i]; + Q+=Charge[i]/10.; + Xm+=X[i]*Charge[i]/10.; + Ym+=Y[i]*Charge[i]/10.; + Zm+=Z[i]*Charge[i]/10.; + Sxx+=X[i]*X[i]*Charge[i]/10.; + Syy+=Y[i]*Y[i]*Charge[i]/10.; + Szz+=Z[i]*Z[i]*Charge[i]/10.; + Sxy+=X[i]*Y[i]*Charge[i]/10.; + Sxz+=X[i]*Z[i]*Charge[i]/10.; + Syz+=Y[i]*Z[i]*Charge[i]/10.; + } + vTrackCharge.push_back(total_charge); + + Xm/=Q; + Ym/=Q; + Zm/=Q; + Sxx/=Q; + Syy/=Q; + Szz/=Q; + Sxy/=Q; + Sxz/=Q; + Syz/=Q; + Sxx-=(Xm*Xm); + Syy-=(Ym*Ym); + Szz-=(Zm*Zm); + Sxy-=(Xm*Ym); + Sxz-=(Xm*Zm); + Syz-=(Ym*Zm); + + theta=0.5*atan((2.*Sxy)/(Sxx-Syy)); + + K11=(Syy+Szz)*pow(cos(theta),2)+(Sxx+Szz)*pow(sin(theta),2)-2.*Sxy*cos(theta)*sin(theta); + K22=(Syy+Szz)*pow(sin(theta),2)+(Sxx+Szz)*pow(cos(theta),2)+2.*Sxy*cos(theta)*sin(theta); + K12=-Sxy*(pow(cos(theta),2)-pow(sin(theta),2))+(Sxx-Syy)*cos(theta)*sin(theta); + K10=Sxz*cos(theta)+Syz*sin(theta); + K01=-Sxz*sin(theta)+Syz*cos(theta); + K00=Sxx+Syy; + + c2=-K00-K11-K22; + c1=K00*K11+K00*K22+K11*K22-K01*K01-K10*K10; + c0=K01*K01*K11+K10*K10*K22-K00*K11*K22; + + + p=c1-pow(c2,2)/3.; + q=2.*pow(c2,3)/27.-c1*c2/3.+c0; + r=pow(q/2.,2)+pow(p,3)/27.; + + + if(r>0) dm2=-c2/3.+pow(-q/2.+sqrt(r),1./3.)+pow(-q/2.-sqrt(r),1./3.); + if(r<0) + { + rho=sqrt(-pow(p,3)/27.); + phi=acos(-q/(2.*rho)); + dm2=min(-c2/3.+2.*pow(rho,1./3.)*cos(phi/3.),min(-c2/3.+2.*pow(rho,1./3.)*cos((phi+2.*TMath::Pi())/3.),-c2/3.+2.*pow(rho,1./3.)*cos((phi+4.*TMath::Pi())/3.))); + } + + a=-K10*cos(theta)/(K11-dm2)+K01*sin(theta)/(K22-dm2); + b=-K10*sin(theta)/(K11-dm2)-K01*cos(theta)/(K22-dm2); + + Xh=((1.+b*b)*Xm-a*b*Ym+a*Zm)/(1.+a*a+b*b); + Yh=((1.+a*a)*Ym-a*b*Xm+b*Zm)/(1.+a*a+b*b); + Zh=((a*a+b*b)*Zm+a*Xm+b*Ym)/(1.+a*a+b*b); + + V1.SetXYZ(Xm,Ym,Zm); + V2.SetXYZ(Xh,Yh,Zh); + + return(fabs(dm2/Q)); +} diff --git a/NPLib/TrackReconstruction/NPRansac.h b/NPLib/TrackReconstruction/NPRansac.h new file mode 100644 index 000000000..2428c5571 --- /dev/null +++ b/NPLib/TrackReconstruction/NPRansac.h @@ -0,0 +1,117 @@ +#ifndef __RANSAC__ +#define __RANSAC__ +/***************************************************************************** + * 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 : Pierre MORFOUACE contact address: morfouace@ganil.fr * + * * + * Creation Date : April 2018 * + * Last update : April 2018 * + *---------------------------------------------------------------------------* + * Decription: * + * This class deal with finding all the track event by event * + *****************************************************************************/ +//C++ Header +#include <stdio.h> +#include <vector> +#include <sstream> +#include <iostream> +#include <fstream> +#include <cmath> +#include <stdlib.h> +#include <limits> +#include <string> +#include <algorithm> + +//NPL +#include "NPTrack.h" +using namespace NPL; + +// ROOT Headers +#include <TLine.h> +#include <TH2F.h> +#include <TH3F.h> +#include <TGraph2D.h> +#include <TMath.h> +#include <TCanvas.h> +#include <TVector3.h> +#include <TRandom.h> +#include <TServerSocket.h> +#include <TSocket.h> +#include <TMonitor.h> +#include <TMessage.h> +#include <TList.h> +#include <TVector.h> + +using namespace std; + +namespace NPL{ + + class Ransac + { + public: + Ransac(); + Ransac(int NumberOfPadsX, int NumberOfPadsY, bool Visu); + ~Ransac(); + + public: + void Reset(); + void ReadParameterValue(string filename); + void Init(vector<int> v1, vector<int> v2, vector<double> v3, vector<double> v4); + vector<NPL::Track> SimpleRansac(); + bool CompareTracksWithBarycenter(NPL::Track track1, NPL::Track track2); + bool CompareTracksWithScalarProduct(NPL::Track track1, NPL::Track track2); + NPL::Track MergeTracks(vector<NPL::Track> tracks); + void DoMerge(string method); + //void CheckTracks(); + + vector<double> GetChargeOfTracks(); + vector<double> GetTrackLength(double PadSizeX, double PadSizeY, double DriftVelocity); + double Fit3D(vector<int> X, vector<int> Y, vector<double> Z, vector<double> Charge, vector<int> inliners, TVector3& V1, TVector3& V2); + + private: + TCanvas* c1; + vector<TLine*> vline; + vector<int> vX, vY; + vector<int> trackX, trackY, trackZ, trackQ; + vector<double> vZ, vQ; + TLine* L; + TGraph2D* h3D; + TGraph2D* pl; + vector<NPL::Track> vTrack; + vector<double> vTrackCharge; + + private: + float fRANSACThreshold; + float fRANSACPointThreshold; + float fRANSACChargeThreshold; + float fRANSACDistance; + float fRANSACMaxIteration; + float fMAXBarycenterDistance; + float fAngleMax; + int fNumberOfTracksMax; + int fOriginalCloudSize; + double fTotalCharge; + int fNumberOfPadsX; + int fNumberOfPadsY; + int fVisu; + bool fMergeWithBarycenter; + bool fMergeWithScalarProduct; + + private: + TServerSocket* m_ServerSocket; + TSocket* m_Socket; + TMonitor* m_Monitor; + TList* m_Histo; + TList* m_Sockets; + + ClassDef(Ransac, 1) + }; +} +#endif diff --git a/NPLib/TrackReconstruction/NPTrack.cxx b/NPLib/TrackReconstruction/NPTrack.cxx new file mode 100644 index 000000000..93b00e8e2 --- /dev/null +++ b/NPLib/TrackReconstruction/NPTrack.cxx @@ -0,0 +1,210 @@ +/***************************************************************************** + * 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 : Pierre MORFOUACE contact address: morfouace@ganil.fr * + * * + * Creation Date : April 2018 * + * Last update : Apro; 2018 * + *---------------------------------------------------------------------------* + * Decription: * + * This class deal with track charactieristic from TPC analysis * + *****************************************************************************/ + + +#include "NPTrack.h" +using namespace NPL; + +using namespace std; + +//ClassImp(NPTrack) + +////////////////////////////////////////////////////// +Track::Track() +{ + /*L2DXY=new TLine(); + L2DXZ=new TLine(); + L2DYZ=new TLine(); + L3D=new TLine();*/ +} + +////////////////////////////////////////////////////// +Track::~Track() +{ + /*delete L2DXY; + delete L2DXZ; + delete L2DYZ; + delete L3D;*/ +} + +////////////////////////////////////////////////////// +TVector3 Track::GetDirectionVector() +{ + TVector3 vTrack = TVector3(Xh-Xm, Yh-Ym, Zh-Zm); + return vTrack; +} + +////////////////////////////////////////////////////// +TVector3 Track::GetVertexPostion(TVector3 vBeamDir, TVector3 vBeamPoint) +{ + //y_beam = Ay_beam*x_beam + By_beam + double Ay_beam = vBeamDir.Y()/vBeamDir.X(); + double By_beam = vBeamPoint.Y() - (vBeamDir.Y()/vBeamDir.X())*vBeamPoint.X(); + //z_beam = Az_beam*x_beam + Bz_beam + double Az_beam = vBeamDir.Z()/vBeamDir.X(); + double Bz_beam = vBeamPoint.Z() - (vBeamDir.Z()/vBeamDir.X())*vBeamPoint.X(); + + //y_track = Ay_track*x_track + By_track + double Ay_track = GetDirectionVector().Y()/GetDirectionVector().X(); + double By_track = Ym - (GetDirectionVector().Y()/GetDirectionVector().X())*Xm; + //z_track = Az_track*x_track + Bz_track + double Az_track = GetDirectionVector().Z()/GetDirectionVector().X(); + double Bz_track = Zm - (GetDirectionVector().Z()/GetDirectionVector().X())*Xm; + + double DBy = By_beam - By_track; + double DBz = Bz_beam - Bz_track; + double alpha = (-Ay_beam*DBy - Az_beam*DBz)/(Ay_beam*Ay_beam + Az_beam*Az_beam + 1); + double beta = (Ay_beam*Ay_track + Az_beam*Az_track + 1)/(Ay_beam*Ay_beam + Az_beam*Az_beam + 1); + + double A = beta*(Ay_beam*Ay_beam + Az_beam*Az_beam + 1) - (Ay_beam*Ay_track + Az_beam*Az_track + 1); + double B = (Ay_track*Ay_track + Az_track*Az_track + 1) - beta*(Ay_beam*Ay_track + Az_beam*Az_track + 1); + double C = beta*(Ay_beam*DBy + Az_beam*DBz) - Ay_track*DBy - Az_track*DBz; + + double xt = -(A*alpha+C)/(A*beta+B); + double xb = beta*xt+alpha; + + double yb = Ay_beam*xb + By_beam; + double zb = Az_beam*xb + Bz_beam; + + double yt = Ay_track*xt + By_track; + double zt = Az_track*xt + Bz_track; + + double xvertex = (xb+xt)/2; + double yvertex = (yb+yt)/2; + double zvertex = (zb+zt)/2; + + TVector3 vVertex = TVector3(xvertex,yvertex,zvertex); + + return vVertex; +} + +////////////////////////////////////////////////////// +TVector3 Track::GetChargeBarycenter() +{ + double bX=0; + double bY=0; + double bZ=0; + double Qtot=0; + + int size = vX.size(); + + for(int i=0; i<size; i++){ + Qtot += (double)vQ[i]; + bX += (double)vX[i]*vQ[i]; + bY += (double)vY[i]*vQ[i]; + bZ += (double)vZ[i]*vQ[i]; + } + + bX=bX/Qtot; + bY=bY/Qtot; + bZ=bZ/Qtot; + + TVector3 vBarycentre = TVector3(bX,bY,bZ); + + return vBarycentre; +} + +////////////////////////////////////////////////////// +TVector3 Track::GetPointBarycenter() +{ + double bX=0; + double bY=0; + double bZ=0; + + int size = vX.size(); + + for(int i=0; i<size; i++){ + bX += (double)vX[i]; + bY += (double)vY[i]; + bZ += (double)vZ[i]; + } + + bX=bX/size; + bY=bY/size; + bZ=bZ/size; + + TVector3 vBarycentre = TVector3(bX,bY,bZ); + + return vBarycentre; +} + +////////////////////////////////////////////////////// +double Track::GetTrackLength(double PadSizeX, double PadSizeY, double DriftVelocity) +{ + double length; + + double Xmax = *max_element(vX.begin(), vX.end())*PadSizeX; + double Xmin = *min_element(vX.begin(), vX.end())*PadSizeX; + + double Ymax = *max_element(vY.begin(), vY.end())*PadSizeY; + double Ymin = *min_element(vY.begin(), vY.end())*PadSizeY; + + double Zmax = *max_element(vZ.begin(), vZ.end())*DriftVelocity; + double Zmin = *min_element(vZ.begin(), vZ.end())*DriftVelocity; + + length = sqrt(pow(Xmax-Xmin,2) + pow(Ymax-Ymin,2) + pow(Zmax-Zmin,2)); + + return length; +} + +////////////////////////////////////////////////////// +double Track::GetTotalCharge() +{ + double Qtot=0; + + int size = vQ.size(); + for(int i=0; i<size; i++){ + Qtot += vQ[i]; + } + Qtot = Qtot/size; + + return Qtot; +} + +////////////////////////////////////////////////////// +void Track::Clear() +{ + vX.clear(); + vY.clear(); + vZ.clear(); + vQ.clear(); +} + +////////////////////////////////////////////////////// +/*void Track::ResetLines() +{ + L2DXY->SetX1(-1); + L2DXY->SetY1(-1); + L2DXY->SetX2(-1); + L2DXY->SetY2(-1); + + L2DXZ->SetX1(-1); + L2DXZ->SetY1(-1); + L2DXZ->SetX2(-1); + L2DXZ->SetY2(-1); + + L2DYZ->SetX1(-1); + L2DYZ->SetY1(-1); + L2DYZ->SetX2(-1); + L2DYZ->SetY2(-1); + + L3D->SetX1(-1); + L3D->SetY1(-1); + L3D->SetX2(-1); + L3D->SetY2(-1); +}*/ diff --git a/NPLib/TrackReconstruction/NPTrack.h b/NPLib/TrackReconstruction/NPTrack.h new file mode 100644 index 000000000..1cb7226bd --- /dev/null +++ b/NPLib/TrackReconstruction/NPTrack.h @@ -0,0 +1,96 @@ +#ifndef __TRACK__ +#define __TRACK__ +/***************************************************************************** + * 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 : Pierre MORFOUACE contact address: morfouace@ganil.fr * + * * + * Creation Date : April 2018 * + * Last update : Apro; 2018 * + *---------------------------------------------------------------------------* + * Decription: * + * This class deal with track charactieristic from TPC analysis * + *****************************************************************************/ + +#include <TLine.h> +#include <TVector3.h> +#include <stdio.h> +#include <iostream> +#include <vector> +#include <algorithm> +#include <cmath> + +using namespace std; + +namespace NPL{ + class Track{ + + public: + Track(); + ~Track(); + public: + double Xm; + double Ym; + double Zm; + double Xh; + double Yh; + double Zh; + + TLine* L2DXY; + TLine* L2DXZ; + TLine* L2DYZ; + TLine* L3D; + + private: + vector<int> vX; + vector<int> vY; + vector<int> vZ; + vector<int> vQ; + + public: + /////////////// + /// SETTERS /// + /////////////// + void SetXPoints(vector<int> vec) {vX=vec;} + void SetYPoints(vector<int> vec) {vY=vec;} + void SetZPoints(vector<int> vec) {vZ=vec;} + void SetQPoints(vector<int> vec) {vQ=vec;} + + /////////////// + /// GETTERS /// + /////////////// + vector<int> GetXPoints() {return vX;} + vector<int> GetYPoints() {return vY;} + vector<int> GetZPoints() {return vZ;} + vector<int> GetQPoints() {return vQ;} + + double GetXm() {return Xm;} + double GetXh() {return Xh;} + double GetYm() {return Ym;} + double GetYh() {return Yh;} + double GetZm() {return Zm;} + double GetZh() {return Zh;} + + public: + TVector3 GetDirectionVector(); + + TVector3 GetVertexPostion(TVector3 vBeamDir, TVector3 vBeamPoint); + + TVector3 GetChargeBarycenter(); + + TVector3 GetPointBarycenter(); + + double GetTrackLength(double PadSizeX, double PadSizeY, double DriftVelocity); + double GetTotalCharge(); + + //void ResetLines(); + void Clear(); + }; +} +#endif diff --git a/NPLib/TrackReconstruction/NPTrackReconstructionLinkDef.h b/NPLib/TrackReconstruction/NPTrackReconstructionLinkDef.h new file mode 100644 index 000000000..058353da8 --- /dev/null +++ b/NPLib/TrackReconstruction/NPTrackReconstructionLinkDef.h @@ -0,0 +1,4 @@ +#ifdef __CINT__ +#pragma link C++ defined_in "./NPRansac.h"; +#pragma link C++ defined_in "./NPTrack.h"; +#endif diff --git a/NPLib/scripts/build_dict.sh b/NPLib/scripts/build_dict.sh index facd09f59..c8ee5388c 100755 --- a/NPLib/scripts/build_dict.sh +++ b/NPLib/scripts/build_dict.sh @@ -53,13 +53,13 @@ fi # Version 5 : generate the dictionnary then the libmap if [ $version_major -eq 5 ] then - rootcint -f $2 -c -I../Core -I../Physics -I../../Core -I../../Physics $1 $5 + rootcint -f $2 -c -I../Core -I../Physics -I../../Core -I../../Physics -I../TrackReconstruction -I../../TrackReconstruction $1 $5 fi # Version 6 or more : generate both at once if [ $version_major -gt 5 ] then - rootcint -f $2 -rmf $3 -rml $lib_name -I../Core -I../Physics -I../../Core -I../../Physics $1 $5 + rootcint -f $2 -rmf $3 -rml $lib_name -I../Core -I../Physics -I../../Core -I../../Physics -I../TrackReconstruction -I../../TrackReconstruction $1 $5 fi diff --git a/NPSimulation/Core/MaterialManager.cc b/NPSimulation/Core/MaterialManager.cc index 703c3dff5..7a3012331 100644 --- a/NPSimulation/Core/MaterialManager.cc +++ b/NPSimulation/Core/MaterialManager.cc @@ -821,18 +821,18 @@ G4Material* MaterialManager::GetGasFromLibrary(string Name, double Pressure, dou if(Name == "H2"){ density = (2*1.00794/Vm)*mg/cm3; - G4Material* material = new G4Material("NPS_"+newName,density,2,kStateGas,Temperature,Pressure); - material->AddElement(GetElementFromLibrary("H"), 1); - material->AddElement(GetElementFromLibrary("H"), 1); + G4Material* material = new G4Material("NPS_"+newName,density,1,kStateGas,Temperature,Pressure); + material->AddElement(GetElementFromLibrary("H"), 2); + //material->AddElement(GetElementFromLibrary("H"), 1); m_Material[Name]=material; return material; } if(Name == "D2"){ density = (2*2.0140/Vm)*mg/cm3; - G4Material* material = new G4Material("NPS_"+newName,density,2,kStateGas,Temperature,Pressure); - material->AddElement(GetElementFromLibrary("D"), 1); - material->AddElement(GetElementFromLibrary("D"), 1); + G4Material* material = new G4Material("NPS_"+newName,density,1,kStateGas,Temperature,Pressure); + material->AddElement(GetElementFromLibrary("D"), 2); + //material->AddElement(GetElementFromLibrary("D"), 1); m_Material[Name]=material; return material; } @@ -850,7 +850,7 @@ G4Material* MaterialManager::GetGasFromLibrary(string Name, double Pressure, dou void MaterialManager::WriteDEDXTable(G4ParticleDefinition* Particle ,G4double Emin,G4double Emax){ map<string,G4Material*>::iterator it; if(Particle->GetPDGCharge()==0) - return; + return; for(it = m_Material.begin() ; it != m_Material.end() ; it++){ // Opening hte output file G4String GlobalPath = getenv("NPTOOL"); @@ -894,7 +894,7 @@ void MaterialManager::WriteDEDXTable(std::set<string> Particle ,G4double Emin,G4 std::set<string>::iterator it; for(it=Particle.begin(); it!=Particle.end() ; it++){ G4ParticleDefinition* p = G4ParticleTable::GetParticleTable()->FindParticle((*it)); - WriteDEDXTable(p,Emin,Emax); + WriteDEDXTable(p,Emin,Emax); } } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... diff --git a/NPSimulation/Core/Target.cc b/NPSimulation/Core/Target.cc index 35b795c4c..166407999 100644 --- a/NPSimulation/Core/Target.cc +++ b/NPSimulation/Core/Target.cc @@ -430,7 +430,7 @@ void Target::SetReactionRegion(){ if(!m_ReactionRegion){ m_ReactionRegion= new G4Region("NPSimulationProcess"); m_ReactionRegion->AddRootLogicalVolume(m_TargetLogic); - m_ReactionRegion->SetUserLimits(new G4UserLimits(m_TargetThickness/10.)); + m_ReactionRegion->SetUserLimits(new G4UserLimits(m_TargetThickness/10.)); } G4FastSimulationManager* mng = m_ReactionRegion->GetFastSimulationManager(); @@ -447,7 +447,7 @@ void Target::SetReactionRegion(){ fsm = new NPS::Decay("Decay",m_ReactionRegion); m_ReactionModel.push_back(fsm); -} +} //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... // Add Detector branch to the EventTree. diff --git a/NPSimulation/Detectors/Actar/Actar.cc b/NPSimulation/Detectors/Actar/Actar.cc index 090dcc5b5..bbe53861b 100644 --- a/NPSimulation/Detectors/Actar/Actar.cc +++ b/NPSimulation/Detectors/Actar/Actar.cc @@ -1,18 +1,18 @@ /***************************************************************************** - * Copyright (C) 2009-2017 this file is part of the NPTool Project * + * Copyright (C) 2009-2017 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: Pierre Morfouace contact address: morfouac@nscl.msu.edu * + * Original Author: Pierre Morfouace contact address: morfouac@nscl.msu.edu * * * * Creation Date : September 2017 * * Last update : * *---------------------------------------------------------------------------* * Decription: * - * This class describe Actar simulation * + * This class describe Actar simulation * * * *---------------------------------------------------------------------------* * Comment: * @@ -53,7 +53,7 @@ // NPTool header #include "Actar.hh" #include "SiliconScorers.hh" -#include "DriftElectronScorers.hh" +#include "TPCScorers.hh" #include "RootOutput.h" #include "MaterialManager.hh" #include "NPSDetectorFactory.hh" @@ -79,39 +79,50 @@ namespace Actar_NS{ // Energy and time Resolution const double ChargeThreshold = 0; const double ResoTime = 0.1*ns ; - //const double ResoEnergy = 1.0*MeV ; - const double ChamberThickness = 55*cm ; - const double ChamberWidth = 50*cm ; + const double ResoCharge = 5./100 ; + const double ChamberThickness = 376*mm ; + const double ChamberWidth = 376*mm ; const double ChamberHeight = 40*cm ; //const int NumberOfPads = 16384; - const int PadX = 128; - const int PadZ = 128; - + //const int PadX = 128; + //const int PadZ = 128; + const double Nose_Rmin = 2.5*cm; const double Nose_Rmax = 3.5*cm; const double Nose_Length = 12*cm; - + const double Mylar_Rmax = 3.5*cm; const double Mylar_Thickness = 7*micrometer; - + const double XGazVolume = 256.*mm; const double YGazVolume = 256.*mm; const double ZGazVolume = 256.*mm; - + const double SiliconHeight = 53.*mm; const double SiliconWidth = 53.*mm; const double SiliconThickness = 0.7*mm; const double DistInterSi = 1.*mm; - const double Si_PosZ=15.*cm; + const double Si_PosZ=175.*mm; const double ResoSilicon = 0.80/2.35; const double EnergyThreshold = 0.1; - + + const double VamosSiliconHeight = 70*mm; + const double VamosSiliconWidth = 50*mm; + const double VamosSiliconThickness = 0.5*mm; + const double VamosSiliconDistanInterSi = 1*mm; + const double VamosSilicon_PosZ = -160*mm; + const double CsIThickness = 1.*cm; const double CsIHeight = 2.5*cm; const double CsIWidth = 2.5*cm; const double DistInterCsI = 1.*mm; const double CsI_PosZ = 16.*cm; const double ResoCsI = 0.200/2.35; + + const double BeamDumpRadius = 30*mm; + const double BeamDumpThickness = 5*mm; + const double BeamDump_PosZ = 160*mm; + } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... @@ -119,20 +130,52 @@ namespace Actar_NS{ // Actar Specific Method Actar::Actar(){ m_Event = new TActarData() ; + m_EventReduced = new MEventReduced(); m_ActarScorer = 0; m_SquareDetector = 0; - + // RGB Color + Transparency - m_VisChamber = new G4VisAttributes(G4Colour(0.7, 0.7, 0.7, 0.3)); - m_VisWindows = new G4VisAttributes(G4Colour(1, 0, 0, 0.25)); - m_VisGas = new G4VisAttributes(G4Colour(0, 0.5, 0.5, 0.3)); - m_VisPads = new G4VisAttributes(G4Colour(255, 223, 50, 0.8)); - m_SiliconVisAtt = new G4VisAttributes(G4Colour(0.529412, 0.807843, 0.980392, 0.95)) ; - m_CsIVisAtt = new G4VisAttributes(G4Colour(0.429412, 0.607843, 0.780392, 0.95)); + m_VisChamber = new G4VisAttributes(G4Colour(0.7, 0.7, 0.7, 0.3)); + m_VisWindows = new G4VisAttributes(G4Colour(1, 0, 0, 0.25)); + m_VisGas = new G4VisAttributes(G4Colour(0, 0.5, 0.5, 0.3)); + m_VisPads = new G4VisAttributes(G4Colour(255, 223, 50, 0.8)); + m_VisMicromegas = new G4VisAttributes(G4Colour(100, 100, 100, 0.4)); + m_SiliconVisAtt = new G4VisAttributes(G4Colour(0.529412, 0.807843, 0.980392, 0.95)) ; + m_CsIVisAtt = new G4VisAttributes(G4Colour(0.429412, 0.607843, 0.780392, 0.95)); + m_BeamDumpVisAtt = new G4VisAttributes(G4Colour(0.9, 0.5, 0.5)); m_VisPads->SetForceWireframe(true); - + + m_build_BeamDump= 0; m_build_Silicon=1; + m_build_Vamos_Silicon=0; m_build_CsI=1; + + // Lookup table // + bool ReadingLookupTable = false; + string LT_FileName = "./Detectors/Actar/LT.dat"; + ifstream LTConfigFile; + LTConfigFile.open(LT_FileName.c_str()); + if(!LTConfigFile.is_open()){ + cout << "No Lookup Table in " << LT_FileName << " found!" << endl; + return; + } + else{ + cout << "/// Using LookupTable from: " << LT_FileName << " ///" << endl; + int co, as, ag, ch; + int pX, pY; + for(int i=0;i<NumberOfCobo*NumberOfASAD*NumberOfAGET*NumberOfChannel;i++){ + LTConfigFile >> co >> as >> ag >> ch >> pX >> pY; + if(pX!=-1 && pY !=-1){ + m_PadToCobo[pX][pY] = co; + m_PadToAsad[pX][pY] = as; + m_PadToAGET[pX][pY] = ag; + m_PadToChannel[pX][pY] = ch; + } + } + ReadingLookupTable = true; + } + LTConfigFile.close(); + } Actar::~Actar(){ @@ -157,47 +200,51 @@ void Actar::AddDetector(double R, double Theta, double Phi, string Shape){ //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... G4LogicalVolume* Actar::BuildDetector(){ - - G4Material* Cu= MaterialManager::getInstance()->GetMaterialFromLibrary("Cu"); - G4Material* Si= MaterialManager::getInstance()->GetMaterialFromLibrary("Si"); - G4Material* Al= MaterialManager::getInstance()->GetMaterialFromLibrary("Al"); - G4Material* Mylar= MaterialManager::getInstance()->GetMaterialFromLibrary("Mylar"); - G4Material* MaterialCsI = MaterialManager::getInstance()->GetMaterialFromLibrary("CsI"); - - if(!m_SquareDetector){ + + G4Material* Cu= MaterialManager::getInstance()->GetMaterialFromLibrary("Cu"); + G4Material* Si= MaterialManager::getInstance()->GetMaterialFromLibrary("Si"); + G4Material* Al= MaterialManager::getInstance()->GetMaterialFromLibrary("Al"); + G4Material* Mylar= MaterialManager::getInstance()->GetMaterialFromLibrary("Mylar"); + G4Material* MaterialCsI = MaterialManager::getInstance()->GetMaterialFromLibrary("CsI"); + + if(!m_SquareDetector){ // Main volume G4Box* sChamber = new G4Box("Actar_Box",Actar_NS::ChamberWidth*0.5, Actar_NS::ChamberHeight*0.5,Actar_NS::ChamberThickness*0.5); - + //Nose volume G4Tubs* sNose = new G4Tubs("Actar_Nose",Actar_NS::Nose_Rmin, Actar_NS::Nose_Rmax,Actar_NS::Nose_Length*0.5, - 0*deg, 360*deg); - + 0*deg, 360*deg); + //Mylar volume G4Tubs* sWindows = new G4Tubs("Actar_Windows",0, Actar_NS::Mylar_Rmax,Actar_NS::Mylar_Thickness*0.5, - 0*deg, 360*deg); - + 0*deg, 360*deg); + // Cage volume G4Box* sCage = new G4Box("Actar_Gas",Actar_NS::XGazVolume*0.5, - Actar_NS::YGazVolume*0.5,Actar_NS::ZGazVolume*0.5); - + Actar_NS::YGazVolume*0.5,Actar_NS::ZGazVolume*0.5); + // Pad - G4Box* sPad = new G4Box("Actar_Pad",2*mm*0.5, - 1*um*0.5,2*mm*0.5); - + G4Box* sPad = new G4Box("Actar_Pad",256*mm*0.5, + 2*mm*0.5,256*mm*0.5); + + // Micromegas + G4Box* sMicromegas = new G4Box("Actar_Micromegas",256*mm*0.5, + 220*micrometer*0.5,256*mm*0.5); + // Cathode - //G4Box* sCathode = new G4Box("Actar_Cathode",26.5*cm*0.5, - // 1*um*0.5,25.6*cm*0.5); - - - + G4Box* sCathode = new G4Box("Actar_Cathode",26.5*cm*0.5, + 1*um*0.5,25.6*cm*0.5); + + + unsigned const int NumberOfGasMix = m_GasMaterial.size(); - + double density=0; double density_sum=0; vector<G4Material*> GasComponent; vector<double> FractionMass; - + for(unsigned int i=0; i<NumberOfGasMix; i++){ GasComponent.push_back(MaterialManager::getInstance()->GetGasFromLibrary(m_GasMaterial[i],m_Pressure,m_Temperature) ); } @@ -206,188 +253,252 @@ G4LogicalVolume* Actar::BuildDetector(){ density_sum += GasComponent[i]->GetDensity(); } //cout << "density = " << density*cm3/g << endl; - + for(unsigned int i=0; i<NumberOfGasMix; i++){ FractionMass.push_back(GasComponent[i]->GetDensity()/density_sum); } - + G4Material* GasMaterial = new G4Material("GasMix", density, NumberOfGasMix, kStateGas, m_Temperature, m_Pressure); - G4Material* DriftGasMaterial = new G4Material("GasMix", density, NumberOfGasMix, kStateGas, m_Temperature, m_Pressure); - + G4Material* DriftGasMaterial = new G4Material("DriftGasMix", density, NumberOfGasMix, kStateGas, m_Temperature, m_Pressure); + for(unsigned int i=0; i<NumberOfGasMix; i++){ GasMaterial->AddMaterial(GasComponent[i], FractionMass[i]); DriftGasMaterial->AddMaterial(GasComponent[i], FractionMass[i]); + cout << GasComponent[i] << endl; } - + G4MaterialPropertiesTable* MPT = new G4MaterialPropertiesTable(); MPT->AddConstProperty("DE_PAIRENERGY",20*eV); - MPT->AddConstProperty("DE_YIELD",1e-2); - //MPT->AddConstProperty("DE_YIELD",1e-1); - //MPT->AddConstProperty("DE_AMPLIFICATION",5); + MPT->AddConstProperty("DE_YIELD",3e-1); + //MPT->AddConstProperty("DE_AMPLIFICATION",2); MPT->AddConstProperty("DE_ABSLENGTH",1*pc); - MPT->AddConstProperty("DE_DRIFTSPEED",5.*cm/microsecond); - //MPT->AddConstProperty("DE_TRANSVERSALSPREAD",5e-5*mm2/ns); - //MPT->AddConstProperty("DE_LONGITUDINALSPREAD",5e-5*mm2/ns); - MPT->AddConstProperty("DE_TRANSVERSALSPREAD",7e-6*mm2/ns); - MPT->AddConstProperty("DE_LONGITUDINALSPREAD",7e-6*mm2/ns); - + MPT->AddConstProperty("DE_DRIFTSPEED",0.8*cm/microsecond); + MPT->AddConstProperty("DE_TRANSVERSALSPREAD",1e-5*mm2/ns); + MPT->AddConstProperty("DE_LONGITUDINALSPREAD",7e-5*mm2/ns); + DriftGasMaterial->SetMaterialPropertiesTable(MPT); - + G4MaterialPropertiesTable* MPT2 = new G4MaterialPropertiesTable(); - MPT2->AddConstProperty("DE_YIELD",1); - MPT2->AddConstProperty("DE_AMPLIFICATION",2); + MPT2->AddConstProperty("DE_AMPLIFICATION",1000); MPT2->AddConstProperty("DE_ABSLENGTH",1*pc); - - Al->SetMaterialPropertiesTable(MPT2); - - m_SquareDetector = new G4LogicalVolume(sChamber,GasMaterial,"logic_Actar_Box",0,0,0); - G4LogicalVolume* logicGas = new G4LogicalVolume(sCage,DriftGasMaterial,"logic_Gas",0,0,0); - G4LogicalVolume* logicNose = new G4LogicalVolume(sNose,Al,"logic_Nose",0,0,0); + + //Al->SetMaterialPropertiesTable(MPT2); + + m_SquareDetector = new G4LogicalVolume(sChamber,GasMaterial,"logic_Actar_Box",0,0,0); + m_logicGas = new G4LogicalVolume(sCage,DriftGasMaterial,"logic_Gas",0,0,0); G4LogicalVolume* logicPad = new G4LogicalVolume(sPad,Cu,"logic_Pad",0,0,0); - //G4LogicalVolume* logicCathode = new G4LogicalVolume(sCathode,Cu,"logic_Cathode",0,0,0); + G4LogicalVolume* logicMicromegas = new G4LogicalVolume(sMicromegas,Al,"logic_Micromegas",0,0,0); + + G4LogicalVolume* logicNose = new G4LogicalVolume(sNose,Cu,"logic_Nose",0,0,0); + G4LogicalVolume* logicCathode = new G4LogicalVolume(sCathode,Cu,"logic_Cathode",0,0,0); G4LogicalVolume* logicWindows = new G4LogicalVolume(sWindows,Mylar,"logic_Windows",0,0,0); - + G4RotationMatrix* Rot = new G4RotationMatrix(); - new G4PVPlacement(G4Transform3D(*Rot,G4ThreeVector(0,0,-Actar_NS::ChamberThickness*0.5+Actar_NS::Nose_Length*0.5)), - logicNose, - "ActarNose",m_SquareDetector,false,0); - - new G4PVPlacement(G4Transform3D(*Rot,G4ThreeVector(0,0,-Actar_NS::ChamberThickness*0.5+Actar_NS::Mylar_Thickness*0.5+Actar_NS::Nose_Length)), - logicWindows, - "ActarEntranceWindows",m_SquareDetector,false,0); - + //new G4PVPlacement(G4Transform3D(*Rot,G4ThreeVector(0,0,-Actar_NS::ChamberThickness*0.5+Actar_NS::Nose_Length*0.5)), + // logicNose, + // "ActarNose",m_SquareDetector,false,0); + + //new G4PVPlacement(G4Transform3D(*Rot,G4ThreeVector(0,0,-Actar_NS::ChamberThickness*0.5+Actar_NS::Mylar_Thickness*0.5+Actar_NS::Nose_Length)), + // logicWindows, + // "ActarEntranceWindows",m_SquareDetector,false,0); + new G4PVPlacement(G4Transform3D(*Rot,G4ThreeVector(0,0,0)), - logicGas, + m_logicGas, "ActarGas",m_SquareDetector,false,0); - - int pad=0; - m_PadToXRow.clear(); - m_PadToZColumn.clear(); - for(int i=0; i<Actar_NS::PadX; i++){ - for(int j=0; j<Actar_NS::PadZ; j++){ - m_PadToXRow[pad] = i; - m_PadToZColumn[pad] = j; - double X=(i-64)*2*mm; - double Z=(j-64)*2*mm; - new G4PVPlacement(G4Transform3D(*Rot,G4ThreeVector(X,Actar_NS::YGazVolume*0.5,Z)), - logicPad, - "ActarPad",logicGas,false,pad+1); - - pad++; - } - } - + + //new G4PVPlacement(G4Transform3D(*Rot,G4ThreeVector(0,Actar_NS::YGazVolume*0.5-0.3*cm,0)), + // logicMicromegas, + // "ActarMicromegas",m_logicGas,false,0); + + new G4PVPlacement(G4Transform3D(*Rot,G4ThreeVector(0,Actar_NS::YGazVolume*0.5,0)), + logicPad, + "ActarPad",m_logicGas,false,0); + + /*int pad=0; + m_PadToXRow.clear(); + m_PadToZColumn.clear(); + for(int i=0; i<Actar_NS::PadX; i++){ + for(int j=0; j<Actar_NS::PadZ; j++){ + m_PadToXRow[pad] = i; + m_PadToZColumn[pad] = j; + double X=(i-64)*2*mm; + double Z=(j-64)*2*mm; + new G4PVPlacement(G4Transform3D(*Rot,G4ThreeVector(X,Actar_NS::YGazVolume*0.5,Z)), + logicPad, + "ActarPad",m_logicGas,false,pad+1); + + pad++; + } + }*/ + /*new G4PVPlacement(G4Transform3D(*Rot,G4ThreeVector(3*cm-0.5*1*um,0,0)), - logicCathode, - "ActarCathode",logicGas,false,0); - - - - new G4PVPlacement(G4Transform3D(*Rot,G4ThreeVector(0,0,-6*cm+6*micrometer)), - logicWindows, - "ActarEntranceWindows",m_SquareDetector,false,0);*/ - - G4ElectricField* field = new G4UniformElectricField(G4ThreeVector(0.0,-100*volt/cm,0.0)); + logicCathode, + "ActarCathode",m_logicGas,false,0); + + + + new G4PVPlacement(G4Transform3D(*Rot,G4ThreeVector(0,0,-6*cm+6*micrometer)), + logicWindows, + "ActarEntranceWindows",m_SquareDetector,false,0);*/ + + G4ElectricField* field = new G4UniformElectricField(G4ThreeVector(0.0,-400*volt/cm,0.0)); // Create an equation of motion for this field G4EqMagElectricField* Equation = new G4EqMagElectricField(field); G4MagIntegratorStepper* Stepper = new G4ClassicalRK4( Equation, 8 ); - + // Get the global field manager G4FieldManager* FieldManager= new G4FieldManager(); // Set this field to the global field manager FieldManager->SetDetectorField(field); - logicGas->SetFieldManager(FieldManager,true); - + m_logicGas->SetFieldManager(FieldManager,true); + G4MagInt_Driver* IntgrDriver = new G4MagInt_Driver(0.1*mm, Stepper, Stepper->GetNumberOfVariables() ); - + G4ChordFinder* ChordFinder = new G4ChordFinder(IntgrDriver); FieldManager->SetChordFinder( ChordFinder ); - - + + logicPad->SetSensitiveDetector(m_ActarScorer); logicNose->SetVisAttributes(m_VisChamber); m_SquareDetector->SetVisAttributes(m_VisChamber); - logicGas->SetVisAttributes(m_VisGas); + m_logicGas->SetVisAttributes(m_VisGas); logicWindows->SetVisAttributes(m_VisWindows); logicPad->SetVisAttributes(m_VisPads); + logicMicromegas->SetVisAttributes(m_VisMicromegas); //m_SquareDetector->SetSensitiveDetector(m_ActarScorer); } - - + + + //////////////////////////////////////////////////// + ///////////////////// Beam Dump //////////////////// + //////////////////////////////////////////////////// + if(m_build_BeamDump){ + G4Tubs* sBeamDump = new G4Tubs("Actar_BeamDump",0*mm, Actar_NS::BeamDumpRadius,Actar_NS::BeamDumpThickness*0.5, + 0*deg, 360*deg); + m_LogicBeamDump = new G4LogicalVolume(sBeamDump, Cu, "logicBeamDump",0,0,0); + + G4ThreeVector positionBeamDump = G4ThreeVector(0, 0, Actar_NS::BeamDump_PosZ); + new G4PVPlacement(new G4RotationMatrix(0,0,0), + positionBeamDump, + m_LogicBeamDump,"BeamDump", + m_SquareDetector,false,0); + + m_LogicBeamDump->SetVisAttributes(m_BeamDumpVisAtt) ; + + } /////////////////////////////////////////////////// ///////////////////// Thin Si ///////////////////// /////////////////////////////////////////////////// + int SiliconNumber=0; if(m_build_Silicon){ G4Box* solidSi = new G4Box("Si", 0.5*Actar_NS::SiliconWidth, 0.5*Actar_NS::SiliconHeight, 0.5*Actar_NS::SiliconThickness); ; m_LogicSilicon = new G4LogicalVolume(solidSi, Si, "logicSi", 0, 0, 0); - - int SiliconNumber=0; + for(int k=0;k<4; k++){ - for(int p=0; p<5; p++){ - double PosX; - double PosY; - if(k==0) PosY= -1.5*Actar_NS::SiliconHeight-2*Actar_NS::DistInterSi; - if(k==1) PosY= -0.5*Actar_NS::SiliconHeight-1*Actar_NS::DistInterSi; - if(k==2) PosY= 0.5*Actar_NS::SiliconHeight+1*Actar_NS::DistInterSi; - if(k==3) PosY= 1.5*Actar_NS::SiliconHeight+2*Actar_NS::DistInterSi; - if(p==0) PosX= -2*Actar_NS::SiliconWidth-2*Actar_NS::DistInterSi; - if(p==1) PosX= -1*Actar_NS::SiliconWidth-1*Actar_NS::DistInterSi; - if(p==2) PosX= 0; - if(p==3) PosX= 1*Actar_NS::SiliconWidth+2*Actar_NS::DistInterSi; - if(p==4) PosX= 2*Actar_NS::SiliconWidth+1*Actar_NS::DistInterSi; - - G4ThreeVector positionSi = G4ThreeVector(PosX, PosY, Actar_NS::Si_PosZ); - new G4PVPlacement(new G4RotationMatrix(0,0,0), - positionSi, - m_LogicSilicon,"Si", - m_SquareDetector,false,SiliconNumber); - SiliconNumber++; + for(int p=0; p<5; p++){ + double PosX; + double PosY; + if(k==0) PosY= -1.5*Actar_NS::SiliconHeight-2*Actar_NS::DistInterSi; + if(k==1) PosY= -0.5*Actar_NS::SiliconHeight-1*Actar_NS::DistInterSi; + if(k==2) PosY= 0.5*Actar_NS::SiliconHeight+1*Actar_NS::DistInterSi; + if(k==3) PosY= 1.5*Actar_NS::SiliconHeight+2*Actar_NS::DistInterSi; + if(p==0) PosX= -2*Actar_NS::SiliconWidth-2*Actar_NS::DistInterSi; + if(p==1) PosX= -1*Actar_NS::SiliconWidth-1*Actar_NS::DistInterSi; + if(p==2) PosX= 0; + if(p==3) PosX= 1*Actar_NS::SiliconWidth+2*Actar_NS::DistInterSi; + if(p==4) PosX= 2*Actar_NS::SiliconWidth+1*Actar_NS::DistInterSi; + + G4ThreeVector positionSi = G4ThreeVector(PosX, PosY, Actar_NS::Si_PosZ); + new G4PVPlacement(new G4RotationMatrix(0,0,0), + positionSi, + m_LogicSilicon,"Si", + m_SquareDetector,false,SiliconNumber); + SiliconNumber++; } - } - + } + // Set Si sensible m_LogicSilicon->SetSensitiveDetector(m_SiliconScorer); - + // Visualisation of ThinSi - m_LogicSilicon->SetVisAttributes(m_SiliconVisAtt) ; + m_LogicSilicon->SetVisAttributes(m_SiliconVisAtt); } - + + //////////////////////////////////////////////////// + ///////////////////// Vamos Si ///////////////////// + //////////////////////////////////////////////////// + if(m_build_Vamos_Silicon){ + G4Box* solidSi = new G4Box("Si", 0.5*Actar_NS::VamosSiliconWidth, 0.5*Actar_NS::VamosSiliconHeight, 0.5*Actar_NS::VamosSiliconThickness); ; + m_LogicVamosSilicon = new G4LogicalVolume(solidSi, Si, "logicVamosSi", 0, 0, 0); + + + int VamosSiliconNumber=0; + for(int k=0;k<4; k++){ + for(int p=0; p<3; p++){ + double PosX; + double PosY; + if(k==0) PosX= -35*mm -0.5*Actar_NS::VamosSiliconWidth - Actar_NS::VamosSiliconDistanInterSi; + if(k==1) PosX= -35*mm -1.5*Actar_NS::VamosSiliconWidth - Actar_NS::VamosSiliconDistanInterSi; + if(k==2) PosX= 35*mm + 0.5*Actar_NS::VamosSiliconWidth + Actar_NS::VamosSiliconDistanInterSi; + if(k==3) PosX= 35*mm + 1.5*Actar_NS::VamosSiliconWidth + Actar_NS::VamosSiliconDistanInterSi; + + if(p==0) PosY= -Actar_NS::VamosSiliconHeight-Actar_NS::VamosSiliconDistanInterSi; + if(p==1) PosY= 0; + if(p==2) PosY= Actar_NS::VamosSiliconHeight+Actar_NS::VamosSiliconDistanInterSi; + + G4ThreeVector positionSi = G4ThreeVector(PosX, PosY, Actar_NS::VamosSilicon_PosZ); + new G4PVPlacement(new G4RotationMatrix(0,0,0), + positionSi, + m_LogicVamosSilicon,"Si", + m_SquareDetector,false,SiliconNumber); + VamosSiliconNumber++; + SiliconNumber++; + } + } + + // Set Si sensible + m_LogicVamosSilicon->SetSensitiveDetector(m_SiliconScorer); + + // Visualisation of ThinSi + m_LogicVamosSilicon->SetVisAttributes(m_SiliconVisAtt); + } + /////////////////////////////////////////////// ///////////////////// CsI ///////////////////// /////////////////////////////////////////////// if(m_build_CsI){ G4Box* solidCsI = new G4Box("Si", 0.5*Actar_NS::CsIWidth, 0.5*Actar_NS::CsIHeight, 0.5*Actar_NS::CsIThickness); ; m_LogicCsICrystal = new G4LogicalVolume(solidCsI, MaterialCsI, "logicCsI", 0, 0, 0); - + int CsINumber=0; for(int k=0;k<8; k++){ - for(int p=0; p<10; p++){ - double PosX; - double PosY; - if(k<4) PosY= -0.5*Actar_NS::CsIHeight-0.5*Actar_NS::DistInterCsI+(k-3)*(Actar_NS::CsIHeight+Actar_NS::DistInterCsI); - if(k>3) PosY= 0.5*Actar_NS::CsIHeight+0.5*Actar_NS::DistInterCsI+(k-4)*(Actar_NS::CsIHeight+Actar_NS::DistInterCsI); - - if(p<5) PosX= 0.5*Actar_NS::CsIWidth+0.5*Actar_NS::DistInterCsI+(4-p)*(Actar_NS::CsIWidth+Actar_NS::DistInterCsI); - if(p>4) PosX= -0.5*Actar_NS::CsIWidth-0.5*Actar_NS::DistInterCsI+(5-p)*(Actar_NS::CsIWidth+Actar_NS::DistInterCsI); - - G4ThreeVector positionCsI = G4ThreeVector(PosX, PosY, Actar_NS::CsI_PosZ); - new G4PVPlacement(new G4RotationMatrix(0,0,0), - positionCsI, - m_LogicCsICrystal,"CsI", - m_SquareDetector,false,CsINumber); - CsINumber++; + for(int p=0; p<10; p++){ + double PosX; + double PosY; + if(k<4) PosY= -0.5*Actar_NS::CsIHeight-0.5*Actar_NS::DistInterCsI+(k-3)*(Actar_NS::CsIHeight+Actar_NS::DistInterCsI); + if(k>3) PosY= 0.5*Actar_NS::CsIHeight+0.5*Actar_NS::DistInterCsI+(k-4)*(Actar_NS::CsIHeight+Actar_NS::DistInterCsI); + + if(p<5) PosX= 0.5*Actar_NS::CsIWidth+0.5*Actar_NS::DistInterCsI+(4-p)*(Actar_NS::CsIWidth+Actar_NS::DistInterCsI); + if(p>4) PosX= -0.5*Actar_NS::CsIWidth-0.5*Actar_NS::DistInterCsI+(5-p)*(Actar_NS::CsIWidth+Actar_NS::DistInterCsI); + + G4ThreeVector positionCsI = G4ThreeVector(PosX, PosY, Actar_NS::CsI_PosZ); + new G4PVPlacement(new G4RotationMatrix(0,0,0), + positionCsI, + m_LogicCsICrystal,"CsI", + m_SquareDetector,false,CsINumber); + CsINumber++; } - } - + } + // Set Si sensible m_LogicCsICrystal->SetSensitiveDetector(m_CsIScorer); - + // Visualisation of ThinSi m_LogicCsICrystal->SetVisAttributes(m_CsIVisAtt) ; } - + return m_SquareDetector; } @@ -403,15 +514,15 @@ void Actar::ReadConfiguration(NPL::InputParser parser){ vector<NPL::InputBlock*> blocks = parser.GetAllBlocksWithToken("Actar"); if(NPOptionManager::getInstance()->GetVerboseLevel()) cout << "//// " << blocks.size() << " detectors found " << endl; - - vector<string> cart = {"POS","Shape","GasMaterial","GasFraction","Temperature","Pressure","Si","CsI"}; - vector<string> sphe = {"R","Theta","Phi","Shape","GasMaterial","GasFraction","Temperature","Pressure","Si","CsI"}; - + + vector<string> cart = {"POS","Shape","GasMaterial","GasFraction","Temperature","Pressure","Si","VamosSi","CsI","BeamDump"}; + //vector<string> sphe = {"R","Theta","Phi","Shape","GasMaterial","GasFraction","Temperature","Pressure","Si","CsI","BeamDump"}; + for(unsigned int i = 0 ; i < blocks.size() ; i++){ if(blocks[i]->HasTokenList(cart)){ if(NPOptionManager::getInstance()->GetVerboseLevel()) cout << endl << "//// Actar " << i+1 << endl; - + G4ThreeVector Pos = NPS::ConvertVector(blocks[i]->GetTVector3("POS","mm")); string Shape = blocks[i]->GetString("Shape"); vector<string> GasName = blocks[i]->GetVectorString("GasMaterial"); @@ -423,11 +534,13 @@ void Actar::ReadConfiguration(NPL::InputParser parser){ m_Temperature = blocks[i]->GetDouble("Temperature","kelvin"); m_Pressure = blocks[i]->GetDouble("Pressure","bar"); m_build_Silicon = blocks[i]->GetInt("Si"); + m_build_Vamos_Silicon = blocks[i]->GetInt("VamosSi"); m_build_CsI = blocks[i]->GetInt("CsI"); - + m_build_BeamDump = blocks[i]->GetInt("BeamDump"); + AddDetector(Pos,Shape); } - else if(blocks[i]->HasTokenList(sphe)){ + /*else if(blocks[i]->HasTokenList(sphe)){ if(NPOptionManager::getInstance()->GetVerboseLevel()) cout << endl << "//// Actar " << i+1 << endl; double R = blocks[i]->GetDouble("R","mm"); @@ -444,9 +557,9 @@ void Actar::ReadConfiguration(NPL::InputParser parser){ m_Pressure = blocks[i]->GetDouble("Pressure","bar"); m_build_Silicon = blocks[i]->GetInt("Si"); m_build_CsI = blocks[i]->GetInt("CsI"); - + AddDetector(R,Theta,Phi,Shape); - } + }*/ else{ cout << "ERROR: check your input file formatting " << endl; exit(1); @@ -461,7 +574,7 @@ void Actar::ReadConfiguration(NPL::InputParser parser){ // Called After DetecorConstruction::AddDetector Method void Actar::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] ) ; @@ -478,13 +591,42 @@ void Actar::ConstructDetector(G4LogicalVolume* world){ G4ThreeVector v = w.cross(u); v = v.unit(); u = u.unit(); - + G4RotationMatrix* Rot = new G4RotationMatrix(u,v,w); - + new G4PVPlacement(G4Transform3D(*Rot,Det_pos), - BuildDetector(), - "Actar",world,false,i+1); + BuildDetector(), + "Actar",world,false,i+1); + } + + if(!m_ReactionRegion){ + G4ProductionCuts* ecut = new G4ProductionCuts(); + ecut->SetProductionCut(1000,"e-"); + + m_ReactionRegion= new G4Region("NPSimulationProcess"); + m_ReactionRegion->SetProductionCuts(ecut); + m_ReactionRegion->AddRootLogicalVolume(m_logicGas); + m_ReactionRegion->SetUserLimits(new G4UserLimits(1.2*mm)); + + G4Region* Region_cut = new G4Region("RegionCut"); + Region_cut->SetProductionCuts(ecut); + Region_cut->AddRootLogicalVolume(m_SquareDetector); + } + + G4FastSimulationManager* mng = m_ReactionRegion->GetFastSimulationManager(); + + unsigned int size = m_ReactionModel.size(); + for(unsigned int i = 0 ; i < size ; i++){ + mng->RemoveFastSimulationModel(m_ReactionModel[i]); } + + m_ReactionModel.clear(); + G4VFastSimulationModel* fsm; + fsm = new NPS::BeamReaction("BeamReaction",m_ReactionRegion); + m_ReactionModel.push_back(fsm); + fsm = new NPS::Decay("Decay",m_ReactionRegion); + m_ReactionModel.push_back(fsm); + } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... // Add Detector branch to the EventTree. @@ -492,29 +634,32 @@ void Actar::ConstructDetector(G4LogicalVolume* world){ void Actar::InitializeRootOutput(){ RootOutput *pAnalysis = RootOutput::getInstance(); TTree *pTree = pAnalysis->GetTree(); - if(!pTree->FindBranch("Actar")){ - pTree->Branch("Actar", "TActarData", &m_Event) ; + if(!pTree->FindBranch("data")){ + //pTree->Branch("Actar", "TActarData", &m_Event) ; + pTree->Branch("data", "MEventReduced", &m_EventReduced) ; } - pTree->SetBranchAddress("Actar", &m_Event) ; + //pTree->SetBranchAddress("Actar", &m_Event) ; + pTree->SetBranchAddress("data", &m_EventReduced) ; } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... // Read sensitive part and fill the Root tree. // Called at in the EventAction::EndOfEventAvtion void Actar::ReadSensitive(const G4Event* event){ - m_Event->Clear(); - + m_EventReduced->CoboAsad.clear(); + + ////////////// // Pad scorer NPS::HitsMap<G4double*>* PadHitMap; std::map<G4int, G4double**>::iterator Pad_itr; - + G4int PadCollectionID = G4SDManager::GetSDMpointer()->GetCollectionID("ActarScorer/Actar_dig"); PadHitMap = (NPS::HitsMap<G4double*>*)(event->GetHCofThisEvent()->GetHC(PadCollectionID)); - // Loop on the Pad map - TH1D* h = new TH1D("h","h",25000,0,25000); + //TH1D* h = new TH1D("h","h",25000,0,25000); for (Pad_itr = PadHitMap->GetMap()->begin() ; Pad_itr != PadHitMap->GetMap()->end() ; Pad_itr++){ + ReducedData DataReduced; G4double* Info = *(Pad_itr->second); // Interraction Coordinates ms_InterCoord->SetDetectedPositionX(Info[2]) ; @@ -522,145 +667,167 @@ void Actar::ReadSensitive(const G4Event* event){ ms_InterCoord->SetDetectedPositionZ(Info[4]) ; ms_InterCoord->SetDetectedAngleTheta(Info[5]/deg) ; ms_InterCoord->SetDetectedAnglePhi(Info[6]/deg) ; - - double Count = Info[0]; - double Time = RandGauss::shoot(Info[1],Actar_NS::ResoTime); + + double Count = RandGauss::shoot(Info[0],Actar_NS::ResoCharge*Info[0]); + double Time = Info[1];//RandGauss::shoot(Info[1],Actar_NS::ResoTime); //int iTime = ((int) Time*20/512)+1; int PadNbr = Info[7]; + int Pad_X = Info[8];//m_PadToXRow[PadNbr]; + int Pad_Y = Info[9];//m_PadToZColumn[PadNbr]; + + int co = m_PadToCobo[Pad_X][Pad_Y]; + int as = m_PadToAsad[Pad_X][Pad_Y]; + int ag = m_PadToAGET[Pad_X][Pad_Y]; + int ch = m_PadToChannel[Pad_X][Pad_Y]; + if(Count>Actar_NS::ChargeThreshold){ - m_Event->SetTime(Time); - m_Event->SetPadNumber(PadNbr); - m_Event->SetCharge(Count); - m_Event->SetRowNumber(m_PadToXRow[PadNbr]); - m_Event->SetColumnNumber(m_PadToZColumn[PadNbr]); - } - - if(Count){ - h->Fill(Info[1],Info[0]); + DataReduced.globalchannelid = ch+(ag<<7)+(as<<9)+(co<<11); + DataReduced.peakheight.push_back(Count); + DataReduced.peaktime.push_back(Time); } + m_EventReduced->CoboAsad.push_back(DataReduced); + /*if(Count){ + h->Fill(Info[1],Info[0]); + }*/ } - - vector<double> Q, T; - for(int i=0; i<h->GetNbinsX(); i++){ - double count = h->GetBinContent(i); - double time = h->GetBinCenter(i); - if(count){ - Q.push_back(count); - T.push_back(time+500); - - } - } - // clear map for next event - //SimulateDigitizer(Q,T,1.40*microsecond,0,8750,25,5); - delete h; + + /*vector<double> Q, T; + for(int i=0; i<h->GetNbinsX(); i++){ + double count = h->GetBinContent(i); + double time = h->GetBinCenter(i); + if(count){ + Q.push_back(count); + T.push_back(time+500); + + } + } + // clear map for next event + SimulateDigitizer(Q,T,1.40*microsecond,0,8750,25,5); + delete h;*/ + PadHitMap->clear(); - + // Silicon // if(m_build_Silicon){ + ReducedData DataReduced; + NPS::HitsMap<G4double*>* SiHitMap; std::map<G4int, G4double**>::iterator Si_itr; - + G4int SiCollectionID = G4SDManager::GetSDMpointer()->GetCollectionID("SiliconScorer/SiliconScorer"); SiHitMap = (NPS::HitsMap<G4double*>*)(event->GetHCofThisEvent()->GetHC(SiCollectionID)); - + // Loop on the ThinSi map for (Si_itr = SiHitMap->GetMap()->begin() ; Si_itr != SiHitMap->GetMap()->end() ; Si_itr++){ G4double* Info = *(Si_itr->second); double E_Si = RandGauss::shoot(Info[0],Actar_NS::ResoSilicon); - + + int co=31; + int as=0; + int ag=0; + int ch=Info[7]; + if(E_Si>Actar_NS::EnergyThreshold){ - m_Event->SetSiliconEnergy(E_Si); - m_Event->SetSiliconDetectorNumber(Info[7]); - m_Event->SetSiliconTime(Info[1]); + DataReduced.globalchannelid = ch+(ag<<7)+(as<<9)+(co<<11); + DataReduced.peaktime.push_back(ch); + DataReduced.peakheight.push_back(E_Si); } + m_EventReduced->CoboAsad.push_back(DataReduced); } - + // Clear Map for next event SiHitMap->clear(); } - + // CsI // if(m_build_CsI){ NPS::HitsMap<G4double*>* CsIHitMap; std::map<G4int, G4double**>::iterator CsI_itr; - + G4int CsICollectionID = G4SDManager::GetSDMpointer()->GetCollectionID("CsIScorer/CsI"); CsIHitMap = (NPS::HitsMap<G4double*>*)(event->GetHCofThisEvent()->GetHC(CsICollectionID)); - + // Loop on the CsI map for (CsI_itr = CsIHitMap->GetMap()->begin() ; CsI_itr !=CsIHitMap->GetMap()->end() ; CsI_itr++){ G4double* Info = *(CsI_itr->second); double E_CsI = RandGauss::shoot(Info[0],Actar_NS::ResoCsI); - - if(E_CsI>Actar_NS::EnergyThreshold){ - m_Event->SetCsIEnergy(E_CsI); - m_Event->SetCsICrystalNumber(Info[2]); - } + + /*if(E_CsI>Actar_NS::EnergyThreshold){ + m_Event->SetCsIEnergy(E_CsI); + m_Event->SetCsICrystalNumber(Info[2]); + } + m_EventReduced->CoboAsad.push_back(DataReduced);*/ } // Clear Map for next event CsIHitMap->clear(); } + + } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... -void Actar::SimulateDigitizer(vector<double> E, vector<double> T, double fallTime,double start,double stop, double step,double noise){ - - static string formula; - formula= ""; - static string Es,Ts,var,cond; - static string fall; - fall=std::to_string(fallTime); - - for(unsigned int i = 0 ; i < E.size() ; i++){ - if(E[i]!=0 && T[i]!=0){ - Es = std::to_string(E[i]); - Ts = std::to_string(T[i]); - cond = ")*(x>"+Ts+")+"; - var = "(x-"+Ts+")"; - formula += Es+"*-1*exp(-"+var+"/"+fall+cond; - } - } - formula+="0"; - //cout << formula << endl; - TF1* f = new TF1("f",formula.c_str(),start,stop); - unsigned int size = (stop-start)/step; - for(unsigned int i = 0 ; i < size ; i++){ - double time = start+i*step; - double energy = f->Eval(time)+noise*(1-2*G4UniformRand()); - m_Event->AddEnergyPoint(energy,time); - } - - delete f; -} +/*void Actar::SimulateDigitizer(vector<double> E, vector<double> T, double fallTime,double start,double stop, double step,double noise){ + + static string formula; + formula= ""; + static string Es,Ts,var,cond; + static string fall; + fall=std::to_string(fallTime); + + for(unsigned int i = 0 ; i < E.size() ; i++){ + if(E[i]!=0 && T[i]!=0){ + Es = std::to_string(E[i]); + Ts = std::to_string(T[i]); + cond = ")*(x>"+Ts+")+"; + var = "(x-"+Ts+")"; + formula += Es+"*-1*exp(-"+var+"/"+fall+cond; + } + } + formula+="0"; + //cout << formula << endl; + TF1* f = new TF1("f",formula.c_str(),start,stop); + unsigned int size = (stop-start)/step; + for(unsigned int i = 0 ; i < size ; i++){ + double time = start+i*step; + double energy = f->Eval(time)+noise*(1-2*G4UniformRand()); + } + + delete f; + }*/ //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... //////////////////////////////////////////////////////////////// void Actar::InitializeScorers() { // This check is necessary in case the geometry is reloaded - + bool already_exist = false; vector<G4int> NestingLevel; NestingLevel.push_back(0); NestingLevel.push_back(2); - + m_ActarScorer = CheckScorer("ActarScorer",already_exist) ; m_SiliconScorer = CheckScorer("SiliconScorer",already_exist); + //m_VamosSiliconScorer = CheckScorer("VamosSiliconScorer",already_exist); m_CsIScorer = CheckScorer("CsIScorer",already_exist); - + if(already_exist) return; - - G4VPrimitiveScorer *SiScorer = new SILICONSCORERS::PS_Silicon_Rectangle("SiliconScorer",0,Actar_NS::SiliconHeight,Actar_NS::SiliconWidth,1,1); + + G4VPrimitiveScorer* SiScorer = new SILICONSCORERS::PS_Silicon_Rectangle("SiliconScorer",0,Actar_NS::SiliconHeight,Actar_NS::SiliconWidth,1,1); m_SiliconScorer->RegisterPrimitive(SiScorer); - + + /*G4VPrimitiveScorer* VamosSiScorer = new SILICONSCORERS::PS_Silicon_Rectangle("VamosSiliconScorer",0,Actar_NS::VamosSiliconHeight,Actar_NS::VamosSiliconWidth,1,1); + m_VamosSiliconScorer->RegisterPrimitive(VamosSiScorer);*/ + G4VPrimitiveScorer* CsIScorer= new CALORIMETERSCORERS::PS_Calorimeter("CsI",NestingLevel); m_CsIScorer->RegisterPrimitive(CsIScorer); - + vector<int> level; level.push_back(0); - G4VPrimitiveScorer* Actar_dig= new DRIFTELECTRONSCORERS::PS_DECathode("Actar_dig",0) ; + G4VPrimitiveScorer* Actar_dig= new TPCSCORERS::PS_TPCCathode("Actar_dig",0) ; m_ActarScorer->RegisterPrimitive(Actar_dig); - + G4SDManager::GetSDMpointer()->AddNewDetector(m_ActarScorer); G4SDManager::GetSDMpointer()->AddNewDetector(m_SiliconScorer); + //G4SDManager::GetSDMpointer()->AddNewDetector(m_VamosSiliconScorer); G4SDManager::GetSDMpointer()->AddNewDetector(m_CsIScorer) ; } @@ -686,6 +853,6 @@ extern"C" { NPS::DetectorFactory::getInstance()->AddDetector("Actar",Actar::Construct); } }; - + proxy_nps_Actar p_nps_Actar; } diff --git a/NPSimulation/Detectors/Actar/Actar.hh b/NPSimulation/Detectors/Actar/Actar.hh index 43aecfd54..8b6115c11 100644 --- a/NPSimulation/Detectors/Actar/Actar.hh +++ b/NPSimulation/Detectors/Actar/Actar.hh @@ -32,11 +32,23 @@ using namespace std; #include "G4RotationMatrix.hh" #include "G4LogicalVolume.hh" #include "G4MultiFunctionalDetector.hh" +#include "G4UserLimits.hh" +#include "G4VFastSimulationModel.hh" +#include "G4FastSimulationManager.hh" // NPTool header #include "NPSVDetector.hh" #include "TActarData.h" +#include "MEventReduced.h" #include "NPInputParser.h" +#include "Decay.hh" +#include "BeamReaction.hh" + +#define NumberOfCobo 16 +#define NumberOfASAD 4 +#define NumberOfAGET 4 +#define NumberOfChannel 68 + class Actar : public NPS::VDetector{ //////////////////////////////////////////////////// @@ -60,10 +72,15 @@ public: private: G4LogicalVolume* m_SquareDetector; + G4LogicalVolume* m_logicGas; bool m_build_Silicon; + bool m_build_Vamos_Silicon; bool m_build_CsI; + bool m_build_BeamDump; G4LogicalVolume* m_LogicSilicon; + G4LogicalVolume* m_LogicVamosSilicon; G4LogicalVolume* m_LogicCsICrystal; + G4LogicalVolume* m_LogicBeamDump; //////////////////////////////////////////////////// ////// Inherite from NPS::VDetector class ///////// @@ -94,11 +111,13 @@ public: // Scorer G4MultiFunctionalDetector* m_ActarScorer ; G4MultiFunctionalDetector* m_CsIScorer ; G4MultiFunctionalDetector* m_SiliconScorer ; + //G4MultiFunctionalDetector* m_VamosSiliconScorer ; //////////////////////////////////////////////////// ///////////Event class to store Data//////////////// //////////////////////////////////////////////////// private: TActarData* m_Event ; + MEventReduced* m_EventReduced; //////////////////////////////////////////////////// ///////////////Private intern Data////////////////// @@ -110,12 +129,16 @@ private: // Geometry vector<double> m_Phi; // Shape type - vector<string> m_Shape ; + vector<string> m_Shape; // map map<int, int> m_PadToXRow; map<int, int> m_PadToZColumn; - + int m_PadToCobo[128][128]; //! + int m_PadToAsad[128][128]; //! + int m_PadToAGET[128][128]; //! + int m_PadToChannel[128][128]; //! + // token vector<string> m_GasMaterial; vector<int> m_GasFraction; @@ -125,11 +148,21 @@ private: // Geometry // Visualisation Attribute G4VisAttributes* m_VisChamber; G4VisAttributes* m_VisWindows; + G4VisAttributes* m_VisMicromegas; G4VisAttributes* m_VisGas; G4VisAttributes* m_VisPads; G4VisAttributes* m_SiliconVisAtt; G4VisAttributes* m_CsIVisAtt; + G4VisAttributes* m_BeamDumpVisAtt; + // Needed for dynamic loading of the library + +private: + // Region were reaction can occure: + G4Region* m_ReactionRegion; + vector<G4VFastSimulationModel*> m_ReactionModel; + + public: static NPS::VDetector* Construct(); }; diff --git a/NPSimulation/EventGenerator/EventGeneratorIsotropic.cc b/NPSimulation/EventGenerator/EventGeneratorIsotropic.cc index 96397b44b..f56243e19 100644 --- a/NPSimulation/EventGenerator/EventGeneratorIsotropic.cc +++ b/NPSimulation/EventGenerator/EventGeneratorIsotropic.cc @@ -41,6 +41,7 @@ using namespace CLHEP; //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... EventGeneratorIsotropic::EventGeneratorIsotropic(){ m_ParticleStack = ParticleStack::getInstance(); + event_ID=0; } @@ -59,7 +60,7 @@ EventGeneratorIsotropic::SourceParameters::SourceParameters(){ m_z0 = 0 ; m_SigmaX = 0 ; m_SigmaY = 0 ; - m_particle = NULL; + m_particle = NULL; } //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... @@ -144,6 +145,10 @@ void EventGeneratorIsotropic::GenerateEvent(G4Event*){ G4double theta = acos(cos_theta) ; G4double phi = RandFlat::shoot() * 2 * pi ; G4double particle_energy = par.m_EnergyLow + RandFlat::shoot() * (par.m_EnergyHigh - par.m_EnergyLow) ; + + cout << "Event ID= " << event_ID << " / theta= " << theta*180/3.1415 << " / energy= " << particle_energy << endl; + event_ID++; + // Direction of particle, energy and laboratory angle G4double momentum_x = sin(theta) * cos(phi) ; diff --git a/NPSimulation/EventGenerator/EventGeneratorIsotropic.hh b/NPSimulation/EventGenerator/EventGeneratorIsotropic.hh index d509f8409..c3e18be43 100644 --- a/NPSimulation/EventGenerator/EventGeneratorIsotropic.hh +++ b/NPSimulation/EventGenerator/EventGeneratorIsotropic.hh @@ -46,6 +46,7 @@ public: // Inherit from VEventGenerator Class void InitializeRootOutput() ; private: // Source parameter from input file + G4int event_ID; struct SourceParameters { SourceParameters() ; G4double m_EnergyLow ; // Lower limit of energy range diff --git a/NPSimulation/Process/BeamReaction.cc b/NPSimulation/Process/BeamReaction.cc index 5798ec4da..2a8921d10 100644 --- a/NPSimulation/Process/BeamReaction.cc +++ b/NPSimulation/Process/BeamReaction.cc @@ -101,7 +101,7 @@ G4bool NPS::BeamReaction::ModelTrigger(const G4FastTrack& fastTrack) { fastTrack.GetPrimaryTrack()->GetVolume()->GetLogicalVolume()->GetSolid(); double in = solid->DistanceToOut(P,V); double out = solid->DistanceToOut(P,-V); - double ratio = in / (out+in) ; + double ratio = in / (out+in) ; if(out == 0){// first step of current event rand = G4RandFlat::shoot(); @@ -119,7 +119,7 @@ G4bool NPS::BeamReaction::ModelTrigger(const G4FastTrack& fastTrack) { // shoot = false; if(m_Reaction.IsAllowed(PrimaryTrack->GetKineticEnergy())){ return true; - + } else{ return false; diff --git a/NPSimulation/Scorers/CMakeLists.txt b/NPSimulation/Scorers/CMakeLists.txt index de493f8a6..a0fb63975 100644 --- a/NPSimulation/Scorers/CMakeLists.txt +++ b/NPSimulation/Scorers/CMakeLists.txt @@ -1,2 +1,2 @@ -add_library(NPSScorers SHARED NPSHitsMap.hh CalorimeterScorers.cc SiliconScorers.cc PhotoDiodeScorers.cc ObsoleteGeneralScorers.cc DriftElectronScorers.cc MDMScorer.cc ) +add_library(NPSScorers SHARED NPSHitsMap.hh CalorimeterScorers.cc SiliconScorers.cc PhotoDiodeScorers.cc ObsoleteGeneralScorers.cc DriftElectronScorers.cc TPCScorers.cc MDMScorer.cc ) target_link_libraries(NPSScorers ${ROOT_LIBRARIES} ${Geant4_LIBRARIES} ${NPLib_LIBRARIES} -lNPInitialConditions -lNPInteractionCoordinates) diff --git a/NPSimulation/Scorers/TPCScorers.cc b/NPSimulation/Scorers/TPCScorers.cc new file mode 100644 index 000000000..ab85f926d --- /dev/null +++ b/NPSimulation/Scorers/TPCScorers.cc @@ -0,0 +1,119 @@ +/***************************************************************************** + * 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: Pierre MORFOUACE contact address: morfouace@ganil.fr * + * * + * Creation Date : June 2018 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * Scorer for TPC Drift Electron collector * + * * + *---------------------------------------------------------------------------* + * Comment: * + * This new type of scorer to count drift electron in the cathode * + * * + *****************************************************************************/ +#include "TPCScorers.hh" +#include "G4UnitsTable.hh" +using namespace TPCSCORERS ; + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +PS_TPCCathode::PS_TPCCathode(G4String name,G4int depth) +:G4VPrimitiveScorer(name, depth),HCID(-1){ + m_Index = -1 ; + m_Level = depth; +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +PS_TPCCathode::~PS_TPCCathode(){ +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +G4bool PS_TPCCathode::ProcessHits(G4Step* aStep, G4TouchableHistory*){ + + // contain Energy Time, DetNbr, StripFront and StripBack + G4double* Infos = new G4double[10]; + Infos[0] = 0; + Infos[1] = aStep->GetPreStepPoint()->GetProperTime(); + + m_DetectorNumber = aStep->GetPreStepPoint()->GetTouchableHandle()->GetCopyNumber(m_Level); + m_Position = aStep->GetPreStepPoint()->GetPosition(); + + // Interaction coordinates (used to fill the InteractionCoordinates branch) + Infos[2] = m_Position.x(); + Infos[3] = m_Position.y(); + Infos[4] = m_Position.z(); + Infos[5] = m_Position.theta(); + Infos[6] = m_Position.phi(); + Infos[7] = m_DetectorNumber; + + + G4String PID = aStep->GetTrack()->GetDefinition()->GetParticleName(); + + m_Position = aStep->GetPreStepPoint()->GetTouchableHandle()->GetHistory()->GetTopTransform().TransformPoint(m_Position); + + + Infos[8] = (int)((m_Position.z()+128)/2); + Infos[9] = (int)((m_Position.x()+128)/2); + + m_Index = Infos[8] + 128*Infos[9] ; + + + if(PID=="driftelectron"){ + Infos[0] = aStep->GetTrack()->GetWeight(); + } + + // Check if the particle has interact before, if yes, add up the number of electron. + map<G4int, G4double**>::iterator it; + it= EvtMap->GetMap()->find(m_Index); + if(it!=EvtMap->GetMap()->end()){ + G4double* dummy = *(it->second); + Infos[0]+=dummy[0]; + Infos[1]=dummy[1]; + } + + EvtMap->set(m_Index, Infos); + return TRUE; +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +void PS_TPCCathode::Initialize(G4HCofThisEvent* HCE){ + EvtMap = new NPS::HitsMap<G4double*>(GetMultiFunctionalDetector()->GetName(), GetName()); + if (HCID < 0) { + HCID = GetCollectionID(0); + } + HCE->AddHitsCollection(HCID, (G4VHitsCollection*)EvtMap); +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +void PS_TPCCathode::EndOfEvent(G4HCofThisEvent*){ +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +void PS_TPCCathode::clear(){ + std::map<G4int, G4double**>::iterator MapIterator; + for (MapIterator = EvtMap->GetMap()->begin() ; MapIterator != EvtMap->GetMap()->end() ; MapIterator++){ + delete *(MapIterator->second); + } + + EvtMap->clear(); +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +void PS_TPCCathode::DrawAll(){ + +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +void PS_TPCCathode::PrintAll(){ + G4cout << " MultiFunctionalDet " << detector->GetName() << G4endl ; + G4cout << " PrimitiveScorer " << GetName() << G4endl ; + G4cout << " Number of entries " << EvtMap->entries() << G4endl ; +} +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... diff --git a/NPSimulation/Scorers/TPCScorers.hh b/NPSimulation/Scorers/TPCScorers.hh new file mode 100644 index 000000000..6a3bc6db4 --- /dev/null +++ b/NPSimulation/Scorers/TPCScorers.hh @@ -0,0 +1,94 @@ +#ifndef DECathodeScorers_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: Pierre MORFOUACE contact address: morfouace@ganil.fr * + * * + * Creation Date : July 2018 * + * Last update : * + *---------------------------------------------------------------------------* + * Decription: * + * File old the scorer specific to the Silicon Detector * + * * + *---------------------------------------------------------------------------* + * Comment: * + * This new style of scorer is aim to become the standard way of doing scorer* + * in NPTool. * + *The index is build using the TrackID, Detector Number and Strip Number. * + *The scorer Hold Energy and time together * + *Only one scorer is needed for a detector * + *****************************************************************************/ +#include "G4VPrimitiveScorer.hh" +#include "NPSHitsMap.hh" + +#include <map> +using namespace std; +using namespace CLHEP; + +namespace TPCSCORERS { +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... + class PS_TPCCathode : public G4VPrimitiveScorer{ + + public: // with description + PS_TPCCathode(G4String name,G4int depth=0); + ~PS_TPCCathode(); + + protected: // with description + G4bool ProcessHits(G4Step*, G4TouchableHistory*); + + public: + void Initialize(G4HCofThisEvent*); + void EndOfEvent(G4HCofThisEvent*); + void clear(); + void DrawAll(); + void PrintAll(); + +private: // inherited from G4VPrimitiveScorer + G4int HCID; + NPS::HitsMap<G4double*>* EvtMap; + + private: // Needed for intermediate calculation (avoid multiple instantiation in Processing Hit) + G4int m_Index; + G4int m_Level; + G4int m_DetectorNumber; + G4ThreeVector m_Position; + + }; +//////////////////////////////////////////////////////////////////////////////// + class PS_DEDigitizer : public G4VPrimitiveScorer{ + + public: // with description + PS_DEDigitizer(G4String name,G4int depth=0); + ~PS_DEDigitizer(); + + protected: // with description + G4bool ProcessHits(G4Step*, G4TouchableHistory*); + + public: + void Initialize(G4HCofThisEvent*); + void EndOfEvent(G4HCofThisEvent*); + void clear(); + void DrawAll(); + void PrintAll(); + +private: // inherited from G4VPrimitiveScorer + G4int HCID; + NPS::HitsMap<G4double*>* EvtMap; + + private: // Needed for intermediate calculation (avoid multiple instantiation in Processing Hit) + G4int m_Index; + G4int m_Level; + G4int m_DetectorNumber; + G4ThreeVector m_Position; + + }; + + +} + +#endif diff --git a/Projects/Actar/Analysis.cxx b/Projects/Actar/Analysis.cxx index 23c45664f..8effa663b 100644 --- a/Projects/Actar/Analysis.cxx +++ b/Projects/Actar/Analysis.cxx @@ -6,13 +6,13 @@ *****************************************************************************/ /***************************************************************************** - * Original Author: XAUTHORX contact address: XMAILX * + * Original Author: Morfouace Pierre contact address: morfouace@ganil.fr * * * - * Creation Date : XMONTHX XYEARX * + * Creation Date : April 2018 * * Last update : * *---------------------------------------------------------------------------* * Decription: * - * This class describe Actar analysis project * + * This class describe Actar analysis project * * * *---------------------------------------------------------------------------* * Comment: * @@ -20,10 +20,15 @@ *****************************************************************************/ #include<iostream> + using namespace std; #include"Analysis.h" #include"NPAnalysisFactory.h" #include"NPDetectorManager.h" +#include"RootOutput.h" +#include"RootInput.h" + + //////////////////////////////////////////////////////////////////////////////// Analysis::Analysis(){ } @@ -33,39 +38,168 @@ Analysis::~Analysis(){ //////////////////////////////////////////////////////////////////////////////// void Analysis::Init(){ - Actar= (TActarPhysics*) m_DetectorManager->GetDetector("Actar"); + Actar= (TActarPhysics*) m_DetectorManager->GetDetector("Actar"); + + Actar->ReadAnalysisConfig(); + if(Actar->GetRansacStatus()){ + Actar->SetRansacParameter("./configs/RansacConfig.dat"); + } + + DriftVelocity = Actar->GetDriftVelocity(); + PadSizeX = Actar->GetPadSizeX(); + PadSizeY = Actar->GetPadSizeY(); + NumberOfPadsX = Actar->GetNumberOfPadsX(); + NumberOfPadsY = Actar->GetNumberOfPadsY(); + + EnergyLoss_3He = NPL::EnergyLoss("EnergyLossTable/He3_D2_6.24151e+08_295.G4table","G4Table",100); + EnergyLoss_17C = NPL::EnergyLoss("EnergyLossTable/C17_D2_6.24151e+08_295.G4table","G4Table",100); + TheReaction = new NPL::Reaction("17C(d,3He)16B@510"); + + InitOutputBranch(); } //////////////////////////////////////////////////////////////////////////////// void Analysis::TreatEvent(){ - //cout << "/// Size=" << Actar->PadRow.size() << endl; - for(unsigned int i=0; i<Actar->PadRow.size(); i++){ - //cout << "Row= " << Actar->PadRow[i] << endl; - } + ReInitValue(); + + int TrackMult = Actar->GetTrackMult(); + + TVector3 vX = TVector3(1,0,0); + TVector3 aTrack, vB; + + if(TrackMult>1){ + vTrack = Actar->GetTracks(); + double scalarproduct=0; + int BeamTrack=0; + for(unsigned int i=0; i<TrackMult; i++){ + TVector3 vtest = TVector3(vTrack[i].GetDirectionVector().X(),vTrack[i].GetDirectionVector().Y(),vTrack[i].GetDirectionVector().Z()); + TVector3 vunit = vtest.Unit(); + double scalar = abs(vunit.Dot(vX)); + vScalar.push_back(scalar); + //cout << scalar << endl; + //cout << scalarproduct << endl; + if(scalar>scalarproduct){ + BeamTrack=i; + scalarproduct=scalar; + } + } + + double XBeam = vTrack[BeamTrack].GetDirectionVector().X(); + double YBeam = vTrack[BeamTrack].GetDirectionVector().Y(); + double ZBeam = vTrack[BeamTrack].GetDirectionVector().Z(); + TVector3 vBeam = TVector3(XBeam,YBeam,ZBeam); + + double XBeamPoint = vTrack[BeamTrack].GetXh(); + double YBeamPoint = vTrack[BeamTrack].GetYh(); + double ZBeamPoint = vTrack[BeamTrack].GetZh(); + TVector3 vBeamPos = TVector3(XBeamPoint,YBeamPoint,ZBeamPoint); + + vB = TVector3(XBeam*PadSizeX, YBeam*PadSizeY,ZBeam*DriftVelocity); + BeamAngle = (vX.Angle(vB))*180/TMath::Pi(); + + for(unsigned int i=0; i<TrackMult; i++){ + if(i!=BeamTrack){ + double Xdir = vTrack[i].GetDirectionVector().X(); + double Ydir = vTrack[i].GetDirectionVector().Y(); + double Zdir = vTrack[i].GetDirectionVector().Z(); + + XVertex.push_back(vTrack[i].GetVertexPostion(vBeam,vBeamPos).X()*PadSizeX); + YVertex.push_back(vTrack[i].GetVertexPostion(vBeam,vBeamPos).Y()*PadSizeY); + ZVertex.push_back(vTrack[i].GetVertexPostion(vBeam,vBeamPos).Z()*DriftVelocity); + + aTrack = TVector3(Xdir*PadSizeX, Ydir*PadSizeY, Zdir*DriftVelocity); + + + double angle = vX.Angle(aTrack)*180/TMath::Pi(); + //double angle = vX.Angle(aTrack)*180/TMath::Pi(); + if(angle>90) angle = 180-angle; + + double x1 = vTrack[i].GetXm()*PadSizeX; + double x2 = vTrack[i].GetXh()*PadSizeX; + double y1 = vTrack[i].GetYm()*PadSizeY-0.5*NumberOfPadsY*PadSizeY; + double y2 = vTrack[i].GetYh()*PadSizeY-0.5*NumberOfPadsY*PadSizeY; + double z1 = -(vTrack[i].GetZm()-256)*DriftVelocity; + double z2 = -(vTrack[i].GetZh()-256)*DriftVelocity; + //if(vScalar[i]<0.999)GetMayaSiHitPosition(x1,x2,y1,y2,z1,z2); + + if(XVertex[i]>0 && XVertex[i]<256){ + double SiDistanceToPadPlane = 47*mm; + double LengthInGas = 256-XVertex[i] + SiDistanceToPadPlane; + for(unsigned int k=0; k<Actar->Si_E.size(); k++){ + ESi.push_back(Actar->Si_E[k]); + DE.push_back(vTrack[i].GetTotalCharge()); + double E3 = EnergyLoss_3He.EvaluateInitialEnergy(Actar->Si_E[k]*MeV,LengthInGas*mm,angle*TMath::Pi()/180); + double BeamEnergy = EnergyLoss_17C.Slow(510*MeV,(XVertex[i]+60)*mm, BeamAngle*TMath::Pi()/180); + TheReaction->SetBeamEnergy(BeamEnergy); + ELab.push_back(E3); + ThetaLab.push_back(angle); + TheReaction->SetNuclei3(E3,angle*TMath::Pi()/180); + Ex.push_back(TheReaction->GetExcitation4()); + ThetaCM.push_back(TheReaction->GetThetaCM()*180./TMath::Pi()); + } + } + } + } + } + + //for(unsigned int i=0; i<Actar->PadX.size(); i++){ + //cout << "X= " << Actar->PadX[i] << endl; + //} } //////////////////////////////////////////////////////////////////////////////// void Analysis::End(){ } +//////////////////////////////////////////////////////////////////////////////// +void Analysis::InitOutputBranch() { + RootOutput::getInstance()->GetTree()->Branch("DE",&DE); + RootOutput::getInstance()->GetTree()->Branch("ESi",&ESi); + RootOutput::getInstance()->GetTree()->Branch("ELab",&ELab); + RootOutput::getInstance()->GetTree()->Branch("ThetaLab",&ThetaLab); + RootOutput::getInstance()->GetTree()->Branch("Ex",&Ex); + RootOutput::getInstance()->GetTree()->Branch("ThetaCM",&ThetaCM); + RootOutput::getInstance()->GetTree()->Branch("vScalar",&vScalar); + RootOutput::getInstance()->GetTree()->Branch("XVertex",&XVertex); + RootOutput::getInstance()->GetTree()->Branch("YVertex",&YVertex); + RootOutput::getInstance()->GetTree()->Branch("ZVertex",&ZVertex); + RootOutput::getInstance()->GetTree()->Branch("BeamAngle",&BeamAngle,"BeamAngle/D"); + +} + +//////////////////////////////////////////////////////////////////////////////// +void Analysis::ReInitValue(){ + DE.clear(); + ESi.clear(); + ELab.clear(); + ThetaLab.clear(); + Ex.clear(); + ThetaCM.clear(); + vScalar.clear(); + XVertex.clear(); + YVertex.clear(); + ZVertex.clear(); + BeamAngle=-1000; + +} //////////////////////////////////////////////////////////////////////////////// // Construct Method to be pass to the DetectorFactory // //////////////////////////////////////////////////////////////////////////////// NPL::VAnalysis* Analysis::Construct(){ - return (NPL::VAnalysis*) new Analysis(); + 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; + class proxy{ + public: + proxy(){ + NPL::AnalysisFactory::getInstance()->SetConstructor(Analysis::Construct); + } + }; + + proxy p; } diff --git a/Projects/Actar/Analysis.h b/Projects/Actar/Analysis.h index 075b9abe6..b49b5f0a6 100644 --- a/Projects/Actar/Analysis.h +++ b/Projects/Actar/Analysis.h @@ -1,4 +1,4 @@ -#ifndef Analysis_h +#ifndef Analysis_h #define Analysis_h /***************************************************************************** * Copyright (C) 2009-2016 this file is part of the NPTool Project * @@ -21,22 +21,58 @@ * * *****************************************************************************/ -#include"NPVAnalysis.h" -#include"TActarPhysics.h" +#include "NPVAnalysis.h" +#include "TActarPhysics.h" +#include "NPEnergyLoss.h" +#include "NPReaction.h" +#include "NPTrack.h" + + + class Analysis: public NPL::VAnalysis{ - public: +public: Analysis(); ~Analysis(); - - public: + +public: void Init(); void TreatEvent(); void End(); - - static NPL::VAnalysis* Construct(); - - private: - TActarPhysics* Actar; - + void InitOutputBranch(); + void ReInitValue(); + + + static NPL::VAnalysis* Construct(); + +public: + double DriftVelocity; + double PadSizeX; + double PadSizeY; + int NumberOfPadsX; + int NumberOfPadsY; + + +private: + TActarPhysics* Actar; + + vector<NPL::Track> vTrack; + + double BeamAngle; + vector<double> vScalar; + vector<double> ThetaLab; + vector<double> ELab; + vector<double> ESi; + vector<double> DE; + vector<double> Ex; + vector<double> ThetaCM; + vector<double> XVertex; + vector<double> YVertex; + vector<double> ZVertex; + + NPL::EnergyLoss EnergyLoss_3He; + NPL::EnergyLoss EnergyLoss_17C; + NPL::Reaction* TheReaction; + + }; #endif -- GitLab