From 28a570fde7c011cebee0c60073f85755b7306e6e Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Mon, 5 Aug 2024 09:11:56 +0200 Subject: [PATCH 01/56] DCH v2 digitizer, which smears the position and adds cluster information --- CMakeLists.txt | 1 + DCHdigi/CMakeLists.txt | 13 +- .../dataFormatExtension/driftChamberHit.yaml | 19 + DCHdigi/include/AlgData.h | 593 ++++++++++++++++ DCHdigi/include/DCHdigi.h | 209 ++++++ DCHdigi/src/DCHdigi.cpp | 665 ++++++++++++++++++ DCHdigi/test/runDCHdigi.py | 37 + 7 files changed, 1533 insertions(+), 4 deletions(-) create mode 100644 DCHdigi/include/AlgData.h create mode 100644 DCHdigi/include/DCHdigi.h create mode 100644 DCHdigi/src/DCHdigi.cpp create mode 100644 DCHdigi/test/runDCHdigi.py diff --git a/CMakeLists.txt b/CMakeLists.txt index 198f641..716cb5c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,6 +21,7 @@ find_package(ROOT COMPONENTS RIO Tree MathCore) find_package(EDM4HEP) find_package(k4FWCore) find_package(Gaudi) +find_package(GSL) #--------------------------------------------------------------- include(cmake/Key4hepConfig.cmake) diff --git a/DCHdigi/CMakeLists.txt b/DCHdigi/CMakeLists.txt index e378554..e51e3c7 100644 --- a/DCHdigi/CMakeLists.txt +++ b/DCHdigi/CMakeLists.txt @@ -28,7 +28,7 @@ install(FILES install(FILES dataFormatExtension/driftChamberHit.yaml - DESTINATION "${CMAKE_INSTALL_DATADIR}/extension" COMPONENT dev) + DESTINATION "${CMAKE_INSTALL_PREFIX}/extension" COMPONENT dev) install(FILES "${PROJECT_BINARY_DIR}/libextensionDict_rdict.pcm" @@ -45,12 +45,17 @@ file(GLOB headers gaudi_add_module(${PackageName} SOURCES ${sources} LINK + k4FWCore::k4FWCore + k4FWCore::k4Interface + Gaudi::GaudiAlgLib Gaudi::GaudiKernel EDM4HEP::edm4hep extensionDict - k4FWCore::k4FWCore - k4FWCore::k4Interface DD4hep::DDRec + DD4hep::DDCore + ROOT::MathCore + ROOT::MathMore + GSL::gsl ) target_include_directories(${PackageName} PUBLIC @@ -71,7 +76,7 @@ install(TARGETS ${PackageName} EXPORT ${CMAKE_PROJECT_NAME}Targets RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT bin LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT shlib - PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/@{CMAKE_PROJECT_NAME}" COMPONENT dev + PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${CMAKE_PROJECT_NAME}" COMPONENT dev ) install(FILES ${scripts} DESTINATION test) diff --git a/DCHdigi/dataFormatExtension/driftChamberHit.yaml b/DCHdigi/dataFormatExtension/driftChamberHit.yaml index 41f2d7e..706d733 100644 --- a/DCHdigi/dataFormatExtension/driftChamberHit.yaml +++ b/DCHdigi/dataFormatExtension/driftChamberHit.yaml @@ -3,6 +3,7 @@ schema_version: 1 options: # should getters / setters be prefixed with get / set? getSyntax: True + setSyntax: True # should POD members be exposed with getters/setters in classes that have them as members? exposePODMembers: False includeSubfolder: True @@ -33,6 +34,24 @@ datatypes: - float eDepError // error measured on eDep [GeV]. - uint32_t clusterCount // number of clusters associated to this hit + extension::DriftChamberDigiV2: + Description: "Digitized hit (before tracking) for Drift Chamber v2 (requires data extension)." + Author: "A. Tolosa-Delgado, B. Francois, CERN" + Members: + - uint64_t cellID // ID of the sensor that created this hit + - int32_t type // type of the raw data hit + - int32_t quality // quality bit flag of the hit + - float time // time of the hit [ns] + - float eDep // energy deposited on the hit [GeV] + - float eDepError // error measured on eDep [GeV] + - edm4hep::Vector3d position // point on the sensitive wire (SW) which is closest to the simhit [mm] + - edm4hep::Vector3d position_L // point on the left to the sensitive wire (SW) [mm] + - edm4hep::Vector3d position_R // point on the right to the sensitive wire (SW) [mm] + - edm4hep::Vector3d directionSW // direction of SW + - float distanceToWire // distance hit-wire [mm] + - uint32_t clusterCount // number of clusters associated to this hit + - uint32_t clusterSize // number of electrons per cluster + extension::MCRecoDriftChamberDigiAssociation: Description: "Association between a DriftChamberDigi and the corresponding simulated hit" Author: "B. Francois, CERN" diff --git a/DCHdigi/include/AlgData.h b/DCHdigi/include/AlgData.h new file mode 100644 index 0000000..5289459 --- /dev/null +++ b/DCHdigi/include/AlgData.h @@ -0,0 +1,593 @@ +#ifndef ALGDATA_H_INCLUDED +#define ALGDATA_H_INCLUDED + +#include + +#include "TTree.h" +#include "TChain.h" +#include "TF1.h" +#include "TCanvas.h" +#include "TGraph.h" +#include "TFile.h" +#include +#include "Math/Interpolator.h" +#include "Math/InterpolationTypes.h" +#include +#include + + + +class AlgData{ +public: + inline AlgData(); + inline ~AlgData(); + +public: + inline void read_file(TString dataAlg); + inline TF1* read_graph(TString dataAlg, TString cvName, TString fitName); + + + inline TF1* get_fit(); + inline TFormula* get_formula(); + inline double get_Fitvalue(double betagamma) const; + inline ROOT::Math::Interpolator* Interpvalue(std::vector bg, std::vector Ydata,int Intertype); + inline void Load_file(TString dataAlg); + inline void Load_interp(); + inline double get_MPVExtra (double betagamma) const; + inline double get_SgmExtra (double betagamma) const; + inline double get_MeanExtra1 (double betagamma) const; + inline double get_SgmExtra1 (double betagamma) const; + inline double get_SlopeExtra1 (double betagamma)const; + inline double get_FracExtra1(double betagamma) const; + inline double get_FfracExtra(double betagamma) ; + inline double get_maxEx0(double betagamma); + inline double get_maxExSlp(); + inline double get_ExSgmlep(); + inline double get_ExSgmhad(); + inline double get_Ffrac(double betagamma); + inline double get_Fmpv1(double betagamma); + inline double get_Fsgm1(double betagamma); + inline double get_Fmpv2(double betagamma); + inline double get_Fsgm2(double betagamma); + inline double get_ClSzCorrInt(double betagamma); + inline double get_ClSzCorrSlp(double betagamma); + inline std::vector get_ClSzCorrpmean(double betagamma); + inline std::vector get_ClSzCorrpsgm(double betagamma); + + inline std::vector get_ClSzCorrdgmean(double betagamma); + inline std::vector get_ClSzCorrdgsgm(double betagamma); + + inline std::vector get_ClSzCorrdglfrac(double betagamma); + inline std::vector get_ClSzCorrdglmpvl(double betagamma); + inline std::vector get_ClSzCorrdglsgml(double betagamma); + inline std::vector get_ClSzCorrdglmeang(double betagamma); + inline std::vector get_ClSzCorrdglsgmg(double betagamma); + + +private: + TString DataAlg; + TChain *data1; + TChain *datalep; + TChain *datahad; + TFile *file; + + double bgT,bgTlep,bgThad,tmpmaxEx0Tot,tmpErrmaxEx0Tot,tmpmaxExSlpTot,tmpErrmaxExSlpTot,tmpExSgmTotlep,tmpExSgmTothad; + double tmptFfracTot,tmptFerrfracTot,tmptFmpv1Tot,tmptFerrmpv1Tot,tmptFsgm1Tot,tmptFerrsgm1Tot,tmptFmpv2Tot,tmptFerrmpv2Tot,tmptFsgm2Tot,tmptFerrsgm2Tot; + double tmpCorrIntTot,tmpErrCorrIntTot,tmpCorrSlpTot,tmpErrCorrSlpTot; + + std::vector *tmpCorrmeanSliceTot=nullptr; + std::vector *tmpErrCorrmeanSliceTot=nullptr; + std::vector *tmpCorrsgmSliceTot=nullptr; + std::vector *tmpErrCorrsgmSliceTot=nullptr; + + std::vector *tmpCorrdglfracSliceTot=nullptr; + std::vector *tmpErrCorrdglfracSliceTot=nullptr; + std::vector *tmpCorrdglmeangSliceTot=nullptr; + std::vector *tmpErrCorrdglmeangSliceTot=nullptr; + std::vector *tmpCorrdglsgmgSliceTot=nullptr; + std::vector *tmpErrCorrdglsgmgSliceTot=nullptr; + std::vector *tmpCorrdglmpvSliceTot=nullptr; + std::vector *tmpErrCorrdglmpvSliceTot=nullptr; + std::vector *tmpCorrdglsgmlSliceTot=nullptr; + std::vector *tmpErrCorrdglsgmlSliceTot=nullptr; + + std::vector *tmpCorrdgmeanSliceTot=nullptr; + std::vector *tmpErrCorrdgmeanSliceTot=nullptr; + std::vector *tmpCorrdgsgmSliceTot=nullptr; + std::vector *tmpErrCorrdgsgmSliceTot=nullptr; + + //____________________________________________________// + std::vector bgv,bglep,bghad; + std::vector maxEx0Tot,ErrmaxEx0Tot,maxExSlpTot,ErrmaxExSlpTot,ExSgmTotlep,ExSgmTothad; + std::vector tFfracTot, tFerrfracTot, tFmpv1Tot, tFerrmpv1Tot, tFsgm1Tot, tFerrsgm1Tot, tFmpv2Tot, tFerrmpv2Tot, tFsgm2Tot, tFerrsgm2Tot; + std::vector CorrmeanSliceTot[20],ErrCorrmeanSliceTot[20],CorrsgmSliceTot[20],ErrCorrsgmSliceTot[20]; + std::vector CorrIntTot,ErrCorrIntTot,CorrSlpTot,ErrCorrSlpTot; + std::vector CorrdglfracSliceTot[20],ErrCorrdglfracSliceTot[20],CorrdglmeangSliceTot[20],ErrCorrdglmeangSliceTot[20],CorrdglsgmgSliceTot[20],ErrCorrdglsgmgSliceTot[20],CorrdglmpvSliceTot[20],ErrCorrdglmpvSliceTot[20],CorrdglsgmlSliceTot[20],ErrCorrdglsgmlSliceTot[20]; + std::vector CorrdgmeanSliceTot[20],ErrCorrdgmeanSliceTot[20],CorrdgsgmSliceTot[20],ErrCorrdgsgmSliceTot[20]; + + //__________________________________________// + TF1 *Ft; + TF1 *FitMPVExtra; + TF1 *FitSgmExtra; + TF1 *FitMeanExtra1; + TF1 *FitSgmExtra1; + TF1 *FitSlopeExtra1; + TF1 *FitFracExtra1; + + TFormula *FtFormula; + + std::vector Corrmean; + std::vector Corrsgm; + + std::vector Corrdgmean; + std::vector Corrdgsgm; + + std::vector Corrdglfrac; + std::vector Corrdglmeang; + std::vector Corrdglsgmg; + std::vector Corrdglmpv; + std::vector Corrdglsgml; + + std::vector ClSzCorrpmean; + std::vector ClSzCorrpsgm; + std::vector ClSzCorrdgmean; + std::vector ClSzCorrdgsgm; + std::vector ClSzCorrdglfrac; + std::vector ClSzCorrdglmpvl; + std::vector ClSzCorrdglsgml; + std::vector ClSzCorrdglmeang; + std::vector ClSzCorrdglsgmg; + + double maxExSlp; + double ExSgmlep; + double ExSgmhad; + inline void Calc_maxExSlp(); + inline void Calc_ExSgmlep(); + inline void Calc_ExSgmhad(); + + + + //___________________________________________// + + std::map itpm; + ROOT::Math::Interpolator* itp1; + +}; + + //_______________________________________________// + +AlgData::AlgData(){ + + DataAlg=""; + data1=nullptr; + datalep=nullptr; + datahad=nullptr; + file=nullptr; + + + tmpCorrmeanSliceTot=nullptr; + tmpErrCorrmeanSliceTot=nullptr; + tmpCorrsgmSliceTot=nullptr; + tmpErrCorrsgmSliceTot=nullptr; + + tmpCorrdglfracSliceTot=nullptr; + tmpErrCorrdglfracSliceTot=nullptr; + tmpCorrdglmeangSliceTot=nullptr; + tmpErrCorrdglmeangSliceTot=nullptr; + tmpCorrdglsgmgSliceTot=nullptr; + tmpErrCorrdglsgmgSliceTot=nullptr; + tmpCorrdglmpvSliceTot=nullptr; + tmpErrCorrdglmpvSliceTot=nullptr; + tmpCorrdglsgmlSliceTot=nullptr; + tmpErrCorrdglsgmlSliceTot=nullptr; + + tmpCorrdgmeanSliceTot=nullptr; + tmpErrCorrdgmeanSliceTot=nullptr; + tmpCorrdgsgmSliceTot=nullptr; + tmpErrCorrdgsgmSliceTot=nullptr; + + Ft=nullptr; + FtFormula=nullptr; + FitMPVExtra=nullptr; + FitSgmExtra=nullptr; + FitMeanExtra1=nullptr; + FitSgmExtra1=nullptr; + FitSlopeExtra1=nullptr; + FitFracExtra1=nullptr; + + +} + + AlgData::~AlgData(){ + if(file->IsOpen())file->Close(); + } + + + void AlgData::read_file(TString dataAlg){ + + DataAlg=dataAlg; + + std::cout<<" ---reading of---"<Add(dataAlg.Data()); + datalep->Add(dataAlg.Data()); + datahad->Add(dataAlg.Data()); + + } + + data1->SetBranchAddress("bgT",&bgT); + data1->SetBranchAddress("tmpmaxEx0Tot",&tmpmaxEx0Tot); + data1->SetBranchAddress("tmpErrmaxEx0Tot",&tmpErrmaxEx0Tot); + data1->SetBranchAddress("tmpmaxExSlpTot",&tmpmaxExSlpTot); + data1->SetBranchAddress("tmpErrmaxExSlpTot",&tmpErrmaxExSlpTot); + data1->SetBranchAddress("tmptFfracTot",&tmptFfracTot); + data1->SetBranchAddress("tFerrfracTot",&tmptFerrfracTot); + data1->SetBranchAddress("tmptFerrfracTot",&tmptFmpv1Tot); + data1->SetBranchAddress("tmptFerrmpv1Tot",&tmptFerrmpv1Tot); + data1->SetBranchAddress("tmptFerrmpv1Tot",&tmptFerrmpv1Tot); + data1->SetBranchAddress("tmptFsgm1Tot",&tmptFsgm1Tot); + data1->SetBranchAddress("tmptFerrsgm1Tot",&tmptFerrsgm1Tot); + data1->SetBranchAddress("tmptFmpv2Tot",&tmptFmpv2Tot); + data1->SetBranchAddress("tmptFerrmpv2Tot",&tmptFerrmpv2Tot); + data1->SetBranchAddress("tmptFsgm2Tot",&tmptFsgm2Tot); + data1->SetBranchAddress("tmptFerrsgm2Tot",&tmptFerrsgm2Tot); + + data1->SetBranchAddress("tmpCorrIntTot",&tmpCorrIntTot); + data1->SetBranchAddress("tmpErrCorrIntTot",&tmpErrCorrIntTot); + data1->SetBranchAddress("tmpCorrSlpTot",&tmpCorrSlpTot); + data1->SetBranchAddress("tmpErrCorrSlpTot",&tmpErrCorrSlpTot); + + data1->SetBranchAddress("tmpCorrmeanSliceTot",&tmpCorrmeanSliceTot); + data1->SetBranchAddress("tmpErrCorrmeanSliceTot",&tmpErrCorrmeanSliceTot); + data1->SetBranchAddress("tmpCorrsgmSliceTot",&tmpCorrsgmSliceTot); + data1->SetBranchAddress("tmpErrCorrsgmSliceTot",&tmpErrCorrsgmSliceTot); + + data1->SetBranchAddress("tmpCorrdgmeanSliceTot",&tmpCorrdgmeanSliceTot); + data1->SetBranchAddress("tmpErrCorrdgmeanSliceTot",&tmpErrCorrdgmeanSliceTot); + data1->SetBranchAddress("tmpCorrdgsgmSliceTot",&tmpCorrdgsgmSliceTot); + data1->SetBranchAddress("tmpErrCorrdgsgmSliceTot",&tmpErrCorrdgsgmSliceTot); + + data1->SetBranchAddress("tmpCorrdglfracSliceTot",&tmpCorrdglfracSliceTot); + data1->SetBranchAddress("tmpErrCorrdglfracSliceTot",&tmpErrCorrdglfracSliceTot); + data1->SetBranchAddress("tmpCorrdglmeangSliceTot",&tmpCorrdglmeangSliceTot); + data1->SetBranchAddress("tmpErrCorrdglmeangSliceTot",&tmpErrCorrdglmeangSliceTot); + data1->SetBranchAddress("tmpCorrdglsgmgSliceTot",&tmpCorrdglsgmgSliceTot); + data1->SetBranchAddress("tmpErrCorrdglsgmgSliceTot",&tmpErrCorrdglsgmgSliceTot); + data1->SetBranchAddress("tmpCorrdglmpvSliceTot",&tmpCorrdglmpvSliceTot); + data1->SetBranchAddress("tmpErrCorrdglmpvSliceTot",&tmpErrCorrdglmpvSliceTot); + data1->SetBranchAddress("tmpCorrdglsgmlSliceTot",&tmpCorrdglsgmlSliceTot); + data1->SetBranchAddress("tmpErrCorrdglsgmlSliceTot",&tmpErrCorrdglsgmlSliceTot); + + datalep->SetBranchAddress("bgTlep",&bgTlep); + datalep->SetBranchAddress("tmpExSgmTotlep",&tmpExSgmTotlep); + + datahad->SetBranchAddress("bgThad",&bgThad); + datahad->SetBranchAddress("tmpExSgmTothad",&tmpExSgmTothad); + + + for (int i=0;iGetEntries();i++) { + data1->GetEntry(i); + bgv.push_back(bgT); +// std::cout<size();++j){ + CorrmeanSliceTot[j].push_back(tmpCorrmeanSliceTot->at(j)); + ErrCorrmeanSliceTot[j].push_back(tmpErrCorrmeanSliceTot->at(j)); + CorrsgmSliceTot[j].push_back(tmpCorrsgmSliceTot->at(j)); + ErrCorrsgmSliceTot[j].push_back(tmpErrCorrsgmSliceTot->at(j)); + } + + for( unsigned int n=0;nsize();++n){ + CorrdgmeanSliceTot[n].push_back(tmpCorrdgmeanSliceTot->at(n)); + ErrCorrdgmeanSliceTot[n].push_back(tmpErrCorrdgmeanSliceTot->at(n)); + CorrdgsgmSliceTot[n].push_back(tmpCorrdgsgmSliceTot->at(n)); + ErrCorrdgsgmSliceTot[n].push_back(tmpErrCorrdgsgmSliceTot->at(n)); + } + + for(unsigned int k=0;ksize();++k){ + CorrdglfracSliceTot[k].push_back(tmpCorrdglfracSliceTot->at(k)); + ErrCorrdglfracSliceTot[k].push_back(tmpErrCorrdglfracSliceTot->at(k)); + CorrdglmeangSliceTot[k].push_back(tmpCorrdglmeangSliceTot->at(k)); + ErrCorrdglmeangSliceTot[k].push_back(tmpErrCorrdglmeangSliceTot->at(k)); + CorrdglsgmgSliceTot[k].push_back(tmpCorrdglsgmgSliceTot->at(k)); + ErrCorrdglsgmgSliceTot[k].push_back(tmpErrCorrdglsgmgSliceTot->at(k)); + CorrdglmpvSliceTot[k].push_back(tmpCorrdglmpvSliceTot->at(k)); + ErrCorrdglmpvSliceTot[k].push_back(tmpErrCorrdglmpvSliceTot->at(k)); + CorrdglsgmlSliceTot[k].push_back(tmpCorrdglsgmlSliceTot->at(k)); + ErrCorrdglsgmlSliceTot[k].push_back(tmpErrCorrdglsgmlSliceTot->at(k)); +// std::cout<at(k)<GetEntries();i++) { + datalep->GetEntry(i); + bglep.push_back(bgTlep); + ExSgmTotlep.push_back(tmpExSgmTotlep); +// std::cout<< " bgTlep "<GetEntries();i++) { + datahad->GetEntry(i); + bghad.push_back(bgThad); + ExSgmTothad.push_back(tmpExSgmTothad); + } + + } + + + + TF1* AlgData::read_graph(TString dataAlg, TString cvName, TString fitName){ + DataAlg=dataAlg; + file = TFile::Open(dataAlg.Data(),"read"); + TCanvas *cv=(TCanvas *)file->Get(cvName.Data()); + TGraph *gr=(TGraph *)cv->GetListOfPrimitives()->FindObject("Graph"); + TF1* ft=(TF1*)gr->GetListOfFunctions()->FindObject(fitName.Data()); + TFormula *ftFormula=(TFormula *)ft->GetFormula(); + FtFormula=ftFormula; + return ft; + } + + void AlgData::Load_file(TString dataAlg){ + read_file(dataAlg.Data()); + FitMPVExtra=read_graph(dataAlg.Data(), "cMPVExtrabgTot", "fit_MPV"); + FitSgmExtra=read_graph(dataAlg.Data(), "cSgmExtrabgTot", "fit_sgmEx"); + FitMeanExtra1=read_graph(dataAlg.Data(), "cMeanExtra1bgTot", "expeff"); + FitSgmExtra1=read_graph(dataAlg.Data(), "cSgmExtra1bgTot", "expeffNeg"); + FitSlopeExtra1=read_graph(dataAlg.Data(), "cSlopeExtra1bgTot", "fit_slp"); + FitFracExtra1=read_graph(dataAlg.Data(), "cfracbgTot", "fit_frEx"); + Calc_ExSgmhad(); + Calc_ExSgmlep(); + Calc_maxExSlp(); + } + + TF1* AlgData::get_fit(){ + return Ft; + } + + TFormula * AlgData::get_formula(){ + return FtFormula; + } + + double AlgData::get_MPVExtra (double betagamma) const{ + return FitMPVExtra->Eval(betagamma); + } + + double AlgData::get_SgmExtra(double betagamma) const{ + return FitSgmExtra->Eval(betagamma); + } + + double AlgData::get_MeanExtra1(double betagamma) const{ + return FitMeanExtra1->Eval(betagamma); + } + + double AlgData::get_SgmExtra1(double betagamma) const{ + return FitSgmExtra1->Eval(betagamma); + } + + double AlgData::get_FracExtra1(double betagamma) const{ + return FitFracExtra1->Eval(betagamma); + } + + double AlgData::get_SlopeExtra1(double betagamma) const{ + return FitSlopeExtra1->Eval(betagamma); + } + + + ROOT::Math::Interpolator* AlgData::Interpvalue(std::vectorbg,std::vectorYdata,int Intertype) { + //tipo di interpolazione 0=linear;1=pol;2=cspline;4=akima + return itp1=new ROOT::Math::Interpolator(bg,Ydata,(ROOT::Math::Interpolation::Type)Intertype); + } + + void AlgData::Load_interp(){ + itpm["maxEx0Tot"]=Interpvalue(bgv,maxEx0Tot,4); + itpm["tFfracTot"]=Interpvalue(bgv,tFfracTot,4); + itpm["tFmpv1Tot"]=Interpvalue(bgv,tFmpv1Tot,4); + itpm["tFsgm1Tot"]=Interpvalue(bgv,tFsgm1Tot,4); + itpm["tFmpv2Tot"]=Interpvalue(bgv,tFmpv2Tot,4); + itpm["tFsgm2Tot"]=Interpvalue(bgv,tFsgm2Tot,4); + + itpm["CorrIntTot"]=Interpvalue(bgv,CorrIntTot,4); + itpm["CorrSlpTot"]=Interpvalue(bgv,CorrSlpTot,4); + for(unsigned int i=0;isize();++i){ + TString nameCm="CorrmeanSliceTot"; + TString nameCs="CorrsgmSliceTot"; + Corrmean.push_back(nameCm+i); + Corrsgm.push_back(nameCs+i); + itpm[Corrmean.at(i)]=Interpvalue(bgv, CorrmeanSliceTot[i], 4); + itpm[Corrsgm.at(i)]=Interpvalue(bgv, CorrsgmSliceTot[i], 4); + + } + + for(unsigned int j=0;jsize();++j){ + TString nameCdf="Corrdglfrac"; + TString nameCdm="Corrdglmeang"; + TString nameCds="Corrdglsgmg"; + TString nameCdmpv="Corrdglmpv"; + TString nameCdsgl="Corrdglsgmgl"; + Corrdglfrac.push_back(nameCdf+j); + Corrdglmeang.push_back(nameCdm+j); + Corrdglsgmg.push_back(nameCds+j); + Corrdglmpv.push_back(nameCdmpv+j); + Corrdglsgml.push_back(nameCdsgl+j); + itpm[Corrdglfrac.at(j)]=Interpvalue(bgv, CorrdglfracSliceTot[j], 4); + itpm[Corrdglmeang.at(j)]=Interpvalue(bgv, CorrdglmeangSliceTot[j], 4); + itpm[Corrdglsgmg.at(j)]=Interpvalue(bgv, CorrdglsgmgSliceTot[j], 4); + itpm[Corrdglmpv.at(j)]=Interpvalue(bgv, CorrdglmpvSliceTot[j], 4); + itpm[Corrdglsgml.at(j)]=Interpvalue(bgv, CorrdglsgmlSliceTot[j], 4); + } + + for(unsigned int n=0;nsize();++n){ + TString nameCdmg="Corrdgmean"; + TString nameCdsgg="Corrdgsgm"; + Corrdgmean.push_back(nameCdmg+n); + Corrdgsgm.push_back(nameCdsgg+n); + itpm[Corrdgmean.at(n)]=Interpvalue(bgv, CorrdgmeanSliceTot[n], 4); + itpm[Corrdgsgm.at(n)]=Interpvalue(bgv, CorrdgsgmSliceTot[n], 4); + } + } + + double AlgData::get_maxEx0(double betagamma) { + return itpm["maxEx0Tot"]->Eval(betagamma); + } + double AlgData::get_Ffrac(double betagamma) { + return itpm["tFfracTot"]->Eval(betagamma); + } + double AlgData::get_Fmpv1(double betagamma) { + return itpm["tFmpv1Tot"]->Eval(betagamma); + } + double AlgData::get_Fsgm1(double betagamma) { + return itpm["tFsgm1Tot"]->Eval(betagamma); + } + double AlgData::get_Fmpv2(double betagamma) { + return itpm["tFmpv2Tot"]->Eval(betagamma); + } + double AlgData::get_Fsgm2(double betagamma) { + return itpm["tFsgm2Tot"]->Eval(betagamma); + } + double AlgData::get_ClSzCorrInt(double betagamma){ + return itpm["CorrIntTot"]->Eval(betagamma); + } + double AlgData::get_ClSzCorrSlp(double betagamma){ + return itpm["CorrSlpTot"]->Eval(betagamma); + } + + std::vector AlgData::get_ClSzCorrpmean(double betagamma){ + ClSzCorrpmean.clear(); +// std::cout<<"size "<size()<size();++i){ + ClSzCorrpmean.push_back(itpm[Corrmean.at(i)]->Eval(betagamma)); + } + + return ClSzCorrpmean; + } + + std::vector AlgData::get_ClSzCorrpsgm(double betagamma){ + ClSzCorrpsgm.clear(); + for(unsigned int i=0;isize();++i){ + ClSzCorrpsgm.push_back(itpm[Corrsgm.at(i)]->Eval(betagamma)); + } + return ClSzCorrpsgm; + } + + std::vector AlgData::get_ClSzCorrdglfrac(double betagamma){ + ClSzCorrdglfrac.clear(); + for(unsigned int i=0;isize();++i){ + ClSzCorrdglfrac.push_back(itpm[Corrdglfrac.at(i)]->Eval(betagamma)); + } + return ClSzCorrdglfrac; + } + + std::vector AlgData::get_ClSzCorrdglmeang(double betagamma){ + ClSzCorrdglmeang.clear(); + for(unsigned int i=0;isize();++i){ + ClSzCorrdglmeang.push_back(itpm[Corrdglmeang.at(i)]->Eval(betagamma)); + } + return ClSzCorrdglmeang; + } + + std::vector AlgData::get_ClSzCorrdglsgmg(double betagamma){ + ClSzCorrdglsgmg.clear(); + for(unsigned int i=0;isize();++i){ + ClSzCorrdglsgmg.push_back(itpm[Corrdglsgmg.at(i)]->Eval(betagamma)); + } + return ClSzCorrdglsgmg; + } + + std::vector AlgData::get_ClSzCorrdglmpvl(double betagamma){ + ClSzCorrdglmpvl.clear(); + for(unsigned int i=0;isize();++i){ + ClSzCorrdglmpvl.push_back(itpm[Corrdglmpv.at(i)]->Eval(betagamma)); + } + return ClSzCorrdglmpvl; + } + + std::vector AlgData::get_ClSzCorrdglsgml(double betagamma){ + ClSzCorrdglsgml.clear(); + for(unsigned int i=0;isize();++i){ + ClSzCorrdglsgml.push_back(itpm[Corrdglsgml.at(i)]->Eval(betagamma)); + } + return ClSzCorrdglsgml; + } + + std::vector AlgData::get_ClSzCorrdgmean(double betagamma){ + ClSzCorrdgmean.clear(); + for(unsigned int i=0;isize();++i){ + ClSzCorrdgmean.push_back(itpm[Corrdgmean.at(i)]->Eval(betagamma)); + } + return ClSzCorrdgmean; + } + + std::vector AlgData::get_ClSzCorrdgsgm(double betagamma){ + ClSzCorrdgsgm.clear(); + for(unsigned int i=0;isize();++i){ + ClSzCorrdgsgm.push_back(itpm[Corrdgsgm.at(i)]->Eval(betagamma)); + } + return ClSzCorrdgsgm; + } + + + double AlgData::get_maxExSlp(){ + return maxExSlp; + } + + void AlgData::Calc_maxExSlp(){ + double sum=0.0; + for(unsigned int i=0;iInput collections and prerequisites + * Processor requires a collection of SimTrackerHits
+ * This code uses DD4hep length natural unit (cm), but EDM4hep data is (usually) in mm. Please be careful with units.
+ *

Output

+ * Processor produces collection of Digitized hits of Drift Chamber v2
+ * @param DCH_simhits The name of input collection, type edm4hep::SimTrackerHitCollection
+ * (default name empty)
+ * @param DCH_DigiCollection The name of out collection, type edm4hep::DriftChamberDigiV2Collection
+ * (default name DCH_DigiCollection)
+ * @param DCH_name DCH subdetector name
+ * (default value DCH_v2)
+ * @param fileDataAlg File needed for calculating cluster count and size
+ * (default value /eos/.../DataAlgFORGEANT.root)
+ * @param zResolution_mm Resolution (sigma for gaussian smearing) along the sense wire, in mm
+ * (default value 10 mm)
+ * @param xyResolution_mm Resolution (sigma for gaussian smearing) perpendicular the sense wire, in mm
+ * (default value 10 mm)
+ * @param create_debug_histograms Optional flag to create debug histograms
+ * (default value false)
+ * @param GeoSvcName Geometry service name
+ * (default value GeoSvc)
+ * @param uidSvcName The name of the UniqueIDGenSvc instance
+ * (default value uidSvc)
+ *
+ */ + +#ifndef DCHDIGI_H +#define DCHDIGI_H + +// Gaudi Transformer baseclass headers +#include "Gaudi/Property.h" +#include "GaudiAlg/Transformer.h" +#include "k4FWCore/Transformer.h" + +// Gaudi services +#include "k4Interface/IGeoSvc.h" +#include "k4Interface/IUniqueIDGenSvc.h" + + +// EDM4HEP +#include "edm4hep/SimTrackerHitCollection.h" +#include "edm4hep/ParticleIDData.h" +#include "edm4hep/EventHeaderCollection.h" + +// EDM4HEP extension +#include "extension/DriftChamberDigiV2Collection.h" + + +// DD4hep +#include "DD4hep/Detector.h" // for dd4hep::VolumeManager +#include "DDSegmentation/BitFieldCoder.h" + +// STL +#include +#include + +// data extension for the DCH v2 +#include "DDRec/DCH_info.h" + +// ROOT headers +#include "TVector3.h" +#include "TRandom3.h" +#include "TFile.h" +#include "TH1D.h" + +// Class developed by Walaa for the CLS +#include "AlgData.h" + +/// constant to convert from mm (EDM4hep) to DD4hep (cm) +constexpr double MM_TO_CM = 0.1; + +using colltype_in = edm4hep::SimTrackerHitCollection; +using colltype_out = extension::DriftChamberDigiV2Collection; + +struct DCHdigi final + : k4FWCore::MultiTransformer< + std::tuple( + const colltype_in&, const edm4hep::EventHeaderCollection&)> { + DCHdigi(const std::string& name, ISvcLocator* svcLoc); + + StatusCode initialize() override; + StatusCode finalize() override; + + std::tuple operator()( + const colltype_in& , + const edm4hep::EventHeaderCollection& ) const override; + +private: + + + //------------------------------------------------------------------ + // machinery for geometry + + /// Geometry service name + Gaudi::Property m_geoSvcName{this, "GeoSvcName", "GeoSvc", "The name of the GeoSvc instance"}; + Gaudi::Property m_uidSvcName{this, "uidSvcName", "uidSvc", "The name of the UniqueIDGenSvc instance"}; + + /// Detector name + Gaudi::Property m_DCH_name{this, "DCH_name", "DCH_v2", "Name of the Drift Chamber detector"}; + + /// Pointer to the geometry service + SmartIF m_geoSvc; + + /// Decoder for the cellID + dd4hep::DDSegmentation::BitFieldCoder* m_decoder; + + /// Pointer to drift chamber data extension + dd4hep::rec::DCH_info * dch_data = {nullptr}; + + //------------------------------------------------------------------ + // machinery for smearing the position + + /// along the sense wire position resolution in mm + Gaudi::Property m_z_resolution{this, "zResolution_mm", 10.0, + "Spatial resolution in the z direction (from reading out the wires at both sides) [mm]"}; + /// xy resolution in mm + Gaudi::Property m_xy_resolution{this, "xyResolution_mm", 10., "Spatial resolution in the xy direction [mm]"}; + + /// create seed using the uid + SmartIF m_uidSvc; + /// use thread local engine from C++ standard + inline static thread_local std::mt19937_64 m_engine; + void PrepareRandomEngine(const edm4hep::EventHeaderCollection& headers) const; + + + // Operator std::normal_distribution::operator()(Generator& g) is a non-const member function and thus cannot be called for a constant object. So we defined the distribution as mutable. + // Gaussian random number generator used for the smearing of the z position, in cm! + mutable std::normal_distribution m_gauss_z_cm; + // Gaussian random number generator used for the smearing of the xy position, in cm! + mutable std::normal_distribution m_gauss_xy_cm; + + inline static thread_local TRandom3 myRandom; + //------------------------------------------------------------------ + // ancillary functions + + bool IsFileGood(std::string & ifilename) const {return std::ifstream(ifilename).good(); } + + /// Print algorithm configuration + void PrintConfiguration(std::ostream& io); + + /// Send error message to logger and then throw exception + void ThrowException(std::string s) const; + + int CalculateLayerFromCellID(dd4hep::DDSegmentation::CellID id) const { + return m_decoder->get ( id,"layer" ) + dch_data->nlayersPerSuperlayer*m_decoder->get ( id,"superlayer" ) + 1; + } + + int CalculateNphiFromCellID(dd4hep::DDSegmentation::CellID id) const { + return m_decoder->get ( id,"nphi" ); + } + + TVector3 Convert_EDM4hepVector_to_TVector3(const edm4hep::Vector3d & v, double scale) const { + return {v[0]*scale,v[1]*scale,v[2]*scale}; + }; + edm4hep::Vector3d Convert_TVector3_to_EDM4hepVector(const TVector3 & v, double scale) const{ + return {v.x()*scale,v.y()*scale,v.z()*scale}; + }; + + // the following functions should be upstreamed to the data extension at DD4hep + // to avoid code duplication and keep it centralized + TVector3 Calculate_hitpos_to_wire_vector(int ilayer, int nphi, const TVector3 & hit_position /*in cm*/) const; + TVector3 Calculate_wire_vector_ez (int ilayer, int nphi) const; + TVector3 Calculate_wire_z0_point (int ilayer, int nphi) const; + double Calculate_wire_phi_z0 (int ilayer, int nphi) const; + + double Calculate_phi_rot_equivalent_to_hit_to_wire_distance(int ilayer, double hit_to_wire_distance) const; + + //------------------------------------------------------------------ + // cluster calculation, developed by Walaa + + /// file with distributions to be sampled + Gaudi::Property m_fileDataAlg{this, "fileDataAlg", "/eos/project/f/fccsw-web/www/filesForSimDigiReco/IDEA/DataAlgFORGEANT.root", "ROOT file with cluster size distributions"}; + + /// pointer to wrapper class, which contains the cluster size and number distributions + AlgData * flData; + + /// code developed by Walaa for calculating number of clusters and cluster size + std::pair CalculateClusters(const edm4hep::SimTrackerHit & input_sim_hit) const; + + //------------------------------------------------------------------ + // debug information + + /// Flag to create output file with debug histgrams + Gaudi::Property m_create_debug_histos{this, "create_debug_histograms", false, "Create output file with histograms for debugging"}; + + /// histogram to store distance from hit position to the wire + TH1D * hDpw; + + /// histogram to store distance from hit projection to the wire (should be zero) + TH1D * hDww; + + /// histogram to store smearing along the wire + TH1D * hSz; + + /// histogram to store smearing perpendicular the wire + TH1D * hSxy; + +}; + +DECLARE_COMPONENT(DCHdigi); + +#endif diff --git a/DCHdigi/src/DCHdigi.cpp b/DCHdigi/src/DCHdigi.cpp new file mode 100644 index 0000000..5993d72 --- /dev/null +++ b/DCHdigi/src/DCHdigi.cpp @@ -0,0 +1,665 @@ +#include "DCHdigi.h" + +// STL +#include +#include + +/////////////////////////////////////////////////////////////////////////////////////// +/////////////////////// DCHdigi constructor //////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////// +// -- KeyValues("name of the variable that holds the name of the collection exposed in the python steering file", {"default name for the collection"}), +DCHdigi::DCHdigi(const std::string& name, ISvcLocator* svcLoc) +: MultiTransformer(name, svcLoc, + { + KeyValues("DCH_simhits", {""}), + KeyValues("HeaderName", {"EventHeader"}), + }, + { + KeyValues("DCH_DigiCollection", {"DCH_DigiCollection"}) + } + ) +{ + m_geoSvc = serviceLocator()->service(m_geoSvcName); + m_uidSvc = serviceLocator()->service(m_uidSvcName); +} + +/////////////////////////////////////////////////////////////////////////////////////// +/////////////////////// initialize //////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////// +StatusCode DCHdigi::initialize() { + + if (!m_uidSvc) + ThrowException( "Unable to get UniqueIDGenSvc" ); + + m_gauss_z_cm = std::normal_distribution(0., m_z_resolution.value()*MM_TO_CM ); + m_gauss_xy_cm = std::normal_distribution(0., m_xy_resolution.value()*MM_TO_CM); + + //----------------- + // Retrieve the subdetector + std::string DCH_name(m_DCH_name.value()); + if ( 0 == m_geoSvc->getDetector()->detectors().count(DCH_name) ) + { + ThrowException( "Detector <<" + DCH_name + ">> does not exist." ); + } + + dd4hep::DetElement DCH_DE = m_geoSvc->getDetector()->detectors().at(DCH_name); + + /////////////////////////////////////////////////////////////////////////////////// + /////////////////////////// retrieve data extension ////////////////////////// + /////////////////////////////////////////////////////////////////////////////////// + this->dch_data = DCH_DE.extension(); + + /////////////////////////////////////////////////////////////////////////////////// + + //----------------- + // Retrieve the readout associated with the detector element (subdetector) + dd4hep::SensitiveDetector dch_sd = m_geoSvc->getDetector()->sensitiveDetector(DCH_name); + if(not dch_sd.isValid() ) + ThrowException("No valid Sensitive Detector was found for detector <<" + DCH_name + ">>."); + + dd4hep::Readout dch_readout = dch_sd.readout(); + // set the cellID decoder + m_decoder = dch_readout.idSpec().decoder(); + + /////////////////////////////////////////////////////////////////////////////////// + ///////////////////////// initialize Walaa's code for CLS /////////////////////// + /////////////////////////////////////////////////////////////////////////////////// + debug() << Form("Opening %s...",m_fileDataAlg.value().c_str())<> not found."); + flData = new AlgData(); + flData->Load_file(m_fileDataAlg.value().c_str()); + flData->Load_interp(); + debug() << Form("Opening %s... Done",m_fileDataAlg.value().c_str())<SetDirectory(0); + hDww = new TH1D("hDww", "Distance hit projection to the wire, in cm. Should be zero", 100,0,1); + hDww->SetDirectory(0); + hSz = new TH1D("hSz", "Smearing along the wire, in cm", 100,0,5*m_z_resolution.value()); + hSz->SetDirectory(0); + hSxy = new TH1D("hSxy", "Smearing perpendicular the wire, in cm", 100,0,5*m_xy_resolution.value()); + hSxy->SetDirectory(0); + } + return StatusCode::SUCCESS; + } + + + +/////////////////////////////////////////////////////////////////////////////////////// +/////////////////////// operator() //////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////// +std::tuple +DCHdigi::operator()(const colltype_in& input_sim_hits, + const edm4hep::EventHeaderCollection& headers) const { + + // initialize seed for random engine + this->PrepareRandomEngine( headers ); + + debug() << "Input Sim Hit collection size: " << input_sim_hits.size() << endmsg; + + // Create the collections we are going to return + colltype_out output_digi_hits; + + //loop over hit collection + for (const auto& input_sim_hit : input_sim_hits) + { + dd4hep::DDSegmentation::CellID cellid = input_sim_hit.getCellID(); + int ilayer = this->CalculateLayerFromCellID(cellid ); + int nphi = this->CalculateNphiFromCellID(cellid ); + auto hit_position = Convert_EDM4hepVector_to_TVector3( input_sim_hit.getPosition(), MM_TO_CM ); + + // ------------------------------------------------------------------------- + // calculate hit position projection into the wire + TVector3 hit_to_wire_vector = this->Calculate_hitpos_to_wire_vector(ilayer, nphi,hit_position); + TVector3 hit_projection_on_the_wire = hit_position + hit_to_wire_vector; + if( m_create_debug_histos.value() ) + { + double distance_hit_wire = hit_to_wire_vector.Mag(); + hDpw->Fill(distance_hit_wire); + } + TVector3 wire_direction_ez = this->Calculate_wire_vector_ez(ilayer, nphi); + + // ------------------------------------------------------------------------- + // smear the position + + // smear position along the wire + double smearing_z = m_gauss_z_cm( m_engine ); + if( m_create_debug_histos.value() ) hSz->Fill( smearing_z ); + + hit_projection_on_the_wire += smearing_z*(wire_direction_ez.Unit()); + if( m_create_debug_histos.value() ) + { + // the distance from the hit projection and the wire should be zero + TVector3 dummy_vector = this->Calculate_hitpos_to_wire_vector(ilayer, nphi,hit_projection_on_the_wire); + hDww->Fill( dummy_vector.Mag() ); + } + + // smear position perpendicular to the wire + double smearing_xy = m_gauss_xy_cm( m_engine ); + if( m_create_debug_histos.value() ) hSxy->Fill( smearing_xy ); + float distanceToWire_real = hit_to_wire_vector.Mag(); + + // protect against negative values + float distanceToWire_smeared = std::max(0.0, distanceToWire_real +smearing_xy ); + + double phi_lateral_displacement = this->Calculate_phi_rot_equivalent_to_hit_to_wire_distance(ilayer, distanceToWire_smeared ); + TVector3 left_hit_position = hit_projection_on_the_wire; + TVector3 right_hit_position = hit_projection_on_the_wire; + left_hit_position.RotateZ( -phi_lateral_displacement ); + right_hit_position.RotateZ( phi_lateral_displacement ); + + std::int32_t type = 0; + std::int32_t quality = 0; + float eDepError =0; + // length units back to mm + auto positionSW = Convert_TVector3_to_EDM4hepVector(hit_projection_on_the_wire, 1./MM_TO_CM ); + auto positionSW_L = Convert_TVector3_to_EDM4hepVector(left_hit_position , 1./MM_TO_CM ); + auto positionSW_R = Convert_TVector3_to_EDM4hepVector(right_hit_position , 1./MM_TO_CM ); + auto directionSW = Convert_TVector3_to_EDM4hepVector(wire_direction_ez , 1./MM_TO_CM ); + float distanceToWire = distanceToWire_smeared/MM_TO_CM; + + auto [clusterCount,clusterSize] = CalculateClusters(input_sim_hit); + + // create in place the output object + output_digi_hits.create(input_sim_hit.getCellID(), + type, + quality, + input_sim_hit.getTime(), + input_sim_hit.getEDep(), + eDepError, + positionSW, + positionSW_L, + positionSW_R, + directionSW, + distanceToWire, + clusterCount, + clusterSize + ); + }// end loop over hit collection + + ///////////////////////////////////////////////////////////////// + return std::make_tuple(std::move(output_digi_hits)); +} + +/////////////////////////////////////////////////////////////////////////////////////// +/////////////////////// finalize ////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////// +StatusCode DCHdigi::finalize() +{ + if( m_create_debug_histos.value() ) + { + std::unique_ptr ofile{TFile::Open ( "dch_digi_alg_debug.root", "recreate" ) }; + ofile->cd(); + hDpw->Write(); + hDww->Write(); + hSxy->Write(); + hSz->Write(); + } + + return StatusCode::SUCCESS; +} + +/////////////////////////////////////////////////////////////////////////////////////// +/////////////////////// ThrowException //////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////// +void DCHdigi::ThrowException(std::string s) const { + error() << s.c_str() << endmsg; + throw std::runtime_error(s); + } + +/////////////////////////////////////////////////////////////////////////////////////// +/////////////////////// PrintConfiguration //////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////// +void DCHdigi::PrintConfiguration(std::ostream& io) +{ + io << "DCHdigi will use the following components:\n"; + io << "\tGeometry Service: " << m_geoSvcName.value().c_str() << "\n"; + io << "\tUID Service: " << m_uidSvcName.value().c_str() << "\n"; + io << "\tDetector name: " << m_DCH_name.value().c_str() << "\n"; + io << "\t\t|--Volume bitfield: " << m_decoder->fieldDescription().c_str() << "\n"; + io << "\t\t|--Number of layers: " << dch_data->database.size() << "\n"; + io << "\tCluster distributions taken from: " << m_fileDataAlg.value().c_str() << "\n"; + io << "\tResolution along the wire (mm): " << m_z_resolution.value() << "\n"; + io << "\tResolution perp. to the wire (mm): " << m_xy_resolution.value() << "\n"; + return; +} + +void DCHdigi::PrepareRandomEngine(const edm4hep::EventHeaderCollection& headers) const +{ + uint32_t evt_n = headers[0].getEventNumber(); + uint32_t run_n = headers[0].getRunNumber(); + size_t seed = m_uidSvc->getUniqueID(evt_n, run_n, this->name() ); + m_engine.seed(seed); + // test random engine... + m_engine.discard(10); + myRandom.SetSeed(seed+42); +} + +/////////////////////////////////////////////////////////////////////////////////////// +///// Ancillary functions for calculating the distance to the wire //////// +/////////////////////////////////////////////////////////////////////////////////////// + +double DCHdigi::Calculate_phi_rot_equivalent_to_hit_to_wire_distance(int ilayer, double hit_to_wire_distance) const +{ + auto & l = this->dch_data->database.at(ilayer); + double rz0 = l.radius_sw_z0; + return 2*atan( (hit_to_wire_distance/2.)/rz0 ); +} + + + +TVector3 DCHdigi::Calculate_wire_vector_ez(int ilayer, int nphi) const +{ + auto & l = this->dch_data->database.at(ilayer); + + // See original paper Hoshina et al, Computer Physics Communications 153 (2003) 3 + // eq. 2.9, for the definition of ez, vector along the wire + + // initialize some variables + int stereosign = l.StereoSign(); + double rz0 = l.radius_sw_z0; + double dphi = dch_data->twist_angle; + // kappa is the same as in eq. 2.9 + double kappa = (1./dch_data->Lhalf)*tan(dphi/2); + + //--- calculating wire position + // the points p1 and p2 correspond to the ends of the wire + + // point 1 + // double x1 = rz0; // m + // double y1 = 0.; // m + // double z1 = 0.; // m + double x1 = rz0; // m + double y1 = -stereosign*rz0*kappa*dch_data->Lhalf; // m + double z1 = -dch_data->Lhalf; // m + + TVector3 p1 (x1,y1,z1); + + + // point 2 + double x2 = rz0; // m + double y2 = stereosign*rz0*kappa*dch_data->Lhalf; // m + double z2 = dch_data->Lhalf; // m + + TVector3 p2 (x2,y2,z2); + + // calculate phi rotation of whole twisted tube, ie, rotation at z=0 + double phi_z0 = Calculate_wire_phi_z0(ilayer,nphi); + p1.RotateZ(phi_z0); + p2.RotateZ(phi_z0); + + //--- end calculating wire position + + return (p2-p1).Unit(); + +} + +TVector3 DCHdigi::Calculate_wire_z0_point(int ilayer, int nphi) const +{ + auto & l = this->dch_data->database.at(ilayer); + double rz0 = l.radius_sw_z0; + TVector3 p1 (rz0,0,0); + double phi_z0 = Calculate_wire_phi_z0(ilayer,nphi); + p1.RotateZ(phi_z0); + return p1; +} + +// calculate phi rotation of whole twisted tube, ie, rotation at z=0 +double DCHdigi::Calculate_wire_phi_z0(int ilayer, int nphi) const +{ + auto & l = this->dch_data->database.at(ilayer); + int ncells = l.nwires/2; + double phistep = TMath::TwoPi()/ncells; + double phi_z0 = (nphi + 0.25*(l.layer%2))*phistep; + return phi_z0; +} + + +/////////////////////////////////////////////////////////////////////////////////////// +/////////////////////// Calculate vector from hit position to wire ///////////////// +/////////////////////////////////////////////////////////////////////////////////////// +TVector3 DCHdigi::Calculate_hitpos_to_wire_vector(int ilayer, int nphi, const TVector3 & hit_position /*in cm*/) const +{ + // Solution distance from a point to a line given here: + // https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line#Vector_formulation + TVector3 n = this->Calculate_wire_vector_ez(ilayer, nphi); + TVector3 a = this->Calculate_wire_z0_point (ilayer, nphi); + // Remember using cm as natural units of DD4hep consistently! + // TVector3 p {hit_position.x()*MM_TO_CM,hit_position.y()*MM_TO_CM,hit_position.z()*MM_TO_CM}; + + TVector3 a_minus_p = a - hit_position; + double a_minus_p_dot_n = a_minus_p.Dot( n ); + TVector3 scaled_n = a_minus_p_dot_n * n; + //hit_to_wire_vector = a_minus_p - scaled_n; + return (a_minus_p - scaled_n); +} + +/////////////////////////////////////////////////////////////////////////////////////// +/////////////////////// CalculateNClusters //////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////// +std::pair DCHdigi::CalculateClusters(const edm4hep::SimTrackerHit & input_sim_hit) const +{ + std::pair return_values = {0,0}; + uint32_t & Ncl = return_values.first; + uint32_t & ClSz = return_values.second; + //_________________SET NECESSARY PARAMETERS FOR THE CLS ALGORITHM-----WALAA_________________// + + auto thisParticle = input_sim_hit.getParticle(); + // Parameters needed for the CL Algo //Added by Walaa/////// + ///from Createclusters.cpp//// + // int fNClusters; + double me = 0.511; + // float rnd; + float Eloss= 0.0; + // float DeltaE_per_track= 0.0; + // float EtotCell= 0.0; + int NCl; + int NCl1,NClp; + // float ClSz,ClSzP; + // float Rt=0.87; + float EIzp=15.8; + float ExECl1; + float ExECl; + float cut= 1000;//controlla + // float prc=0.83; + float EIzs=25.6; + // float ratio=prc/EIzs; + // int NCltot=0; + // float Edep=0.0; + // float DeltaE=0.0; + // int count; + // bool loop; + // float prvDiff; + // float tmpDiff[10]; + // float vecExECl[10]; + // float mintmpDiff; + // int iloop; + float ExECl1totRec; + // float SgmaxExECl; + // int Ncl; + float rndCorr; + float maxExECl=0.0; + // float ExSgm=0.0; + float totExECl; +// int ParentID; + const int nhEp=10;//10 + float hEpcut[10]={100,200,300,400,500,600,700,800,900,1000}; + int minE=1000; + int maxE=10000; + int binE=1000; + int nhE=(maxE-minE)/binE; + TString parClass; + // int Ncltot=0; + int NEltot=0; + // float Etot=0.0; + float maxEx0len,ExSgmlen; + int choice= 2; + // int Nev=500000; + // int val; + // float EtCut=0.7; + ///////end from Createclusters.cpp//// + +///////from Createclusters.h///////// + // TF1Convolution **cnvl =new TF1Convolution*[100];//100 for 1 cm gas box //Added by Walaa + // TF1 **fcnvl=new TF1 *[100]; //Added by Walaa + // float fnorm[100]; //Added by Walaa + double vecpar[5]; //Added by Walaa + std::vector vecEtr,vecEtrTot; + float sumVecTot,meanVecTot,sumVec,meanVec; +/////////end from Createclusters.h///////// + int NCld; + TString parName; + double bg, Momentum, mass=-1e300; + std::vector vecExtraD; + + double Ffrac, Fmpv1, Fsgm1, Fmpv2, Fsgm2; + std::vector CorrpMean,CorrpSgm,Corrdgmean,Corrdgsgm,Corrdglfrac,Corrdglmpvl,Corrdglsgml,Corrdglmeang,Corrdglsgmg; + float Ekdelta; + float maxEx0, maxExSlp, ExSgmlep, ExSgmhad; + float MPVEx, SgmEx, MeanEx1, SgmEx1, frac, Slp, CorrSlp, CorrInt; + double LengthTrack, Etot_per_track; + //////end parameters + bool IsSecondaryWithinDCH = false; + { + auto vertex = thisParticle.getVertex(); // in mm + auto vertexRsquared = vertex[0]*vertex[0] + vertex[1]*vertex[1]; + auto vertexZabs = std::fabs(vertex[2]); + float DCH_halflengh = 2000; + float DCH_rin_squared = 350*350; + float DCH_rout_squared = 2000*2000; + IsSecondaryWithinDCH = (vertexZabs < DCH_halflengh) && (vertexRsquared>DCH_rin_squared) && (vertexRsquaredget_Ffrac(bg);//0.9; + Fmpv1=flData->get_Fmpv1(bg);//43; + Fsgm1=flData->get_Fsgm1(bg);//9.64; + Fmpv2=flData->get_Fmpv2(bg);//311.3; + Fsgm2=flData->get_Fsgm2(bg);//35; + CorrpMean=flData->get_ClSzCorrpmean(bg); + CorrpSgm=flData->get_ClSzCorrpsgm(bg); + Corrdgmean=flData->get_ClSzCorrdgmean(bg); + Corrdgsgm=flData->get_ClSzCorrdgsgm(bg); + Corrdglfrac=flData->get_ClSzCorrdglfrac(bg); + Corrdglmpvl=flData->get_ClSzCorrdglmpvl(bg); + Corrdglsgml=flData->get_ClSzCorrdglsgml(bg); + Corrdglmeang=flData->get_ClSzCorrdglmeang(bg); + Corrdglsgmg=flData->get_ClSzCorrdglsgmg(bg); + maxEx0=flData->get_maxEx0(bg);//379.4 electron 100 gev + maxExSlp=flData->get_maxExSlp(); + // lepton PDG id goes from 11 to 16 (antiparticles have negative id) + bool IsLepton = (11 <= abs(pdgid) ) && (16 >= abs(pdgid) ); + if( IsLepton ){ + ExSgmlep=flData->get_ExSgmlep(); + }else{ + ExSgmhad=flData->get_ExSgmhad(); + } + + MPVEx=flData->get_MPVExtra(bg);//103.2 + SgmEx=flData->get_SgmExtra(bg);//28.5;// + MeanEx1=flData->get_MeanExtra1(bg);//13.8;// + SgmEx1=flData->get_SgmExtra1(bg);//9.72;// + frac=flData->get_FracExtra1(bg);//0.13;// + Slp=flData->get_SlopeExtra1(bg);//7.95;// + debug() << " maxEx0 "<< maxEx0<< " ExSgmhad "<get_ClSzCorrSlp(bg); + CorrInt=flData->get_ClSzCorrInt(bg); + + vecpar[0]=Ffrac; + vecpar[1]=Fmpv1; + vecpar[2]=Fsgm1; + vecpar[3]=Fmpv2; + vecpar[4]=Fsgm2; + + double Tmax = (2.0*me*pow(bg,2)/(1+(2.0*(1+pow(bg,2))*me/mass)+pow(me/mass,2)))*1e+6; + float maxEcut=cut; + if(TmaxSetRange(0,maxEcut); + * fcnvl[0]->SetParameters(vecpar[0],vecpar[1],vecpar[2],vecpar[3],vecpar[4]); + * cnvl[0]=nullptr;*/ + + + TF1 *land= new TF1("land","landaun"); + land->SetParameter(0,1); + land->SetParameter(1,MPVEx); + land->SetParameter(2,SgmEx); + land->SetRange(0,maxEcut); + + TF1 *exGauss=new TF1("exGauss","[0]*([1]*TMath::Gaus(x,[2],[3],true)+(1.0-[1])*TMath::Exp(-x/[4])/[4])"); + exGauss->SetParameter(0,1); + exGauss->SetParameter(1,frac); + exGauss->SetParameter(2,MeanEx1); + exGauss->SetParameter(3,SgmEx1); + exGauss->SetParameter(4,Slp); + exGauss->SetRange(0,90); + + + // int MaxEv = Entries > Nev ? Nev : Entries; + // cout<<" MAXEV"<myRandom.Gaus(0,ExSgmlen))/maxExSlp; + // cout<<"maxExECl= "<(EIzp+EIzs)&&maxExECl>totExECl && while1counter<1e6){ + while1counter++; + // cout<<"start again"<Eloss) ExECl=Eloss; + totExECl+=ExECl; + // cout<<"totExECl= " <myRandom.Uniform(0,1); + if(rndCorrmyRandom.Gaus(Corrdglmeang[tmphE],Corrdglsgmg[tmphE]); + }else{ + tmpCl=this->myRandom.Landau(Corrdglmpvl[tmphE],Corrdglsgml[tmphE]); + } + }else{ + tmpCl=this->myRandom.Gaus(Corrdgmean[tmphE],Corrdgsgm[tmphE]); + } + + ClSz=TMath::Nint(vecExtraD[i]*CorrSlp+CorrInt-tmpCl); + if(ClSz<2) {ClSz=2;} + // TODO Alvaro: check what is ClSz??? + // output_digi_hit.setClusterSize(ClSz); + // hClSzRec->Fill(ClSz); + // hClSzDRec->Fill(ClSz); + // fClusterCharge.push_back(ClSz); + NEltot+=ClSz; + + } + + Ncl=NCl1+NClp+NCld; + debug() <<"Ncl= "<< Ncl<<" NCl1= "<size() << endmsg; + + // output_digi_hit.setClusterCount(Ncl); + + /* for (int icl=0;icl Date: Thu, 8 Aug 2024 11:44:39 +0200 Subject: [PATCH 02/56] remove gaudi transformer linking/header --- DCHdigi/CMakeLists.txt | 1 - DCHdigi/include/DCHdigi.h | 1 - 2 files changed, 2 deletions(-) diff --git a/DCHdigi/CMakeLists.txt b/DCHdigi/CMakeLists.txt index e51e3c7..7158903 100644 --- a/DCHdigi/CMakeLists.txt +++ b/DCHdigi/CMakeLists.txt @@ -47,7 +47,6 @@ gaudi_add_module(${PackageName} LINK k4FWCore::k4FWCore k4FWCore::k4Interface - Gaudi::GaudiAlgLib Gaudi::GaudiKernel EDM4HEP::edm4hep extensionDict diff --git a/DCHdigi/include/DCHdigi.h b/DCHdigi/include/DCHdigi.h index 0df9a61..92e1c15 100644 --- a/DCHdigi/include/DCHdigi.h +++ b/DCHdigi/include/DCHdigi.h @@ -36,7 +36,6 @@ // Gaudi Transformer baseclass headers #include "Gaudi/Property.h" -#include "GaudiAlg/Transformer.h" #include "k4FWCore/Transformer.h" // Gaudi services From 8b8ab07e39bc2ba805d4bd3755960499b5817b35 Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Thu, 8 Aug 2024 11:50:19 +0200 Subject: [PATCH 03/56] filter out the new digitizer if DCH data extension is not found --- DCHdigi/CMakeLists.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/DCHdigi/CMakeLists.txt b/DCHdigi/CMakeLists.txt index 7158903..0f6fd62 100644 --- a/DCHdigi/CMakeLists.txt +++ b/DCHdigi/CMakeLists.txt @@ -42,6 +42,16 @@ file(GLOB headers ${PROJECT_SOURCE_DIR}/include/*.h ) +include(CheckIncludeFileCXX) +set(CMAKE_REQUIRED_LIBRARIES DD4hep::DDRec) +CHECK_INCLUDE_FILE_CXX(DDRec/DCH_info.h DCH_INFO_H_EXIST) +set(CMAKE_REQUIRED_LIBRARIES) +set(FILES_DEPENDINGON_DCH_INFO_H "DCHdigi.cpp" ) +if(NOT DCH_INFO_H_EXIST) + list(FILTER sources EXCLUDE REGEX "${FILES_DEPENDINGON_DCH_INFO_H}") + message(WARNING "Gaudi algorithm defined in ${FILES_DEPENDINGON_DCH_INFO_H} will not be built because header file DDRec/DCH_info.h was not found") +endif() + gaudi_add_module(${PackageName} SOURCES ${sources} LINK From 703a26e399fe4e01bfa812ee69644eb49a84b9e0 Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Fri, 9 Aug 2024 09:43:20 +0200 Subject: [PATCH 04/56] update test of idea vx --- VTXdigi/test/runVTXdigitizer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VTXdigi/test/runVTXdigitizer.py b/VTXdigi/test/runVTXdigitizer.py index bbf65da..aee01f7 100644 --- a/VTXdigi/test/runVTXdigitizer.py +++ b/VTXdigi/test/runVTXdigitizer.py @@ -66,7 +66,7 @@ path_to_detector = os.environ.get("K4GEO", "") # Previously used "FCCDETECTORS" print(path_to_detector) detectors_to_use=[ - 'FCCee/IDEA/compact/IDEA_o1_v03/IDEA_o1_v03.xml', + 'FCCee/IDEA/compact/IDEA_o1_v02/IDEA_o1_v03.xml', # 'FCCee/CLD/compact/CLD_o2_v05/CLD_o2_v05.xml', ] # prefix all xmls with path_to_detector From 33a72aa895f31167073a05cdb85843fada214040 Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Fri, 9 Aug 2024 09:57:42 +0200 Subject: [PATCH 05/56] fix vx test --- VTXdigi/test/runVTXdigitizer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VTXdigi/test/runVTXdigitizer.py b/VTXdigi/test/runVTXdigitizer.py index aee01f7..bbf65da 100644 --- a/VTXdigi/test/runVTXdigitizer.py +++ b/VTXdigi/test/runVTXdigitizer.py @@ -66,7 +66,7 @@ path_to_detector = os.environ.get("K4GEO", "") # Previously used "FCCDETECTORS" print(path_to_detector) detectors_to_use=[ - 'FCCee/IDEA/compact/IDEA_o1_v02/IDEA_o1_v03.xml', + 'FCCee/IDEA/compact/IDEA_o1_v03/IDEA_o1_v03.xml', # 'FCCee/CLD/compact/CLD_o2_v05/CLD_o2_v05.xml', ] # prefix all xmls with path_to_detector From 5be43354d0a3d6ea3ecbd3cb6c0051df41139d6d Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Fri, 9 Aug 2024 13:29:00 +0200 Subject: [PATCH 06/56] remove position_L/R member of data extension --- DCHdigi/dataFormatExtension/driftChamberHit.yaml | 2 -- DCHdigi/src/DCHdigi.cpp | 10 ---------- 2 files changed, 12 deletions(-) diff --git a/DCHdigi/dataFormatExtension/driftChamberHit.yaml b/DCHdigi/dataFormatExtension/driftChamberHit.yaml index 706d733..d934d3b 100644 --- a/DCHdigi/dataFormatExtension/driftChamberHit.yaml +++ b/DCHdigi/dataFormatExtension/driftChamberHit.yaml @@ -45,8 +45,6 @@ datatypes: - float eDep // energy deposited on the hit [GeV] - float eDepError // error measured on eDep [GeV] - edm4hep::Vector3d position // point on the sensitive wire (SW) which is closest to the simhit [mm] - - edm4hep::Vector3d position_L // point on the left to the sensitive wire (SW) [mm] - - edm4hep::Vector3d position_R // point on the right to the sensitive wire (SW) [mm] - edm4hep::Vector3d directionSW // direction of SW - float distanceToWire // distance hit-wire [mm] - uint32_t clusterCount // number of clusters associated to this hit diff --git a/DCHdigi/src/DCHdigi.cpp b/DCHdigi/src/DCHdigi.cpp index 5993d72..98fcb5b 100644 --- a/DCHdigi/src/DCHdigi.cpp +++ b/DCHdigi/src/DCHdigi.cpp @@ -148,19 +148,11 @@ DCHdigi::operator()(const colltype_in& input_sim_hits, // protect against negative values float distanceToWire_smeared = std::max(0.0, distanceToWire_real +smearing_xy ); - double phi_lateral_displacement = this->Calculate_phi_rot_equivalent_to_hit_to_wire_distance(ilayer, distanceToWire_smeared ); - TVector3 left_hit_position = hit_projection_on_the_wire; - TVector3 right_hit_position = hit_projection_on_the_wire; - left_hit_position.RotateZ( -phi_lateral_displacement ); - right_hit_position.RotateZ( phi_lateral_displacement ); - std::int32_t type = 0; std::int32_t quality = 0; float eDepError =0; // length units back to mm auto positionSW = Convert_TVector3_to_EDM4hepVector(hit_projection_on_the_wire, 1./MM_TO_CM ); - auto positionSW_L = Convert_TVector3_to_EDM4hepVector(left_hit_position , 1./MM_TO_CM ); - auto positionSW_R = Convert_TVector3_to_EDM4hepVector(right_hit_position , 1./MM_TO_CM ); auto directionSW = Convert_TVector3_to_EDM4hepVector(wire_direction_ez , 1./MM_TO_CM ); float distanceToWire = distanceToWire_smeared/MM_TO_CM; @@ -174,8 +166,6 @@ DCHdigi::operator()(const colltype_in& input_sim_hits, input_sim_hit.getEDep(), eDepError, positionSW, - positionSW_L, - positionSW_R, directionSW, distanceToWire, clusterCount, From d54728a12d4945ba86ea0af9a0f5512d26d8bf3c Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Fri, 9 Aug 2024 15:11:17 +0200 Subject: [PATCH 07/56] add test for DCHdigi --- DCHdigi/include/DCHdigi.h | 4 +- .../test/test_DCHdigi/check_DCHdigi_output.py | 34 + .../compact/DCH_standalone_o1_v02.xml | 197 ++++ .../test_DCHdigi/compact/elements_o1_v01.xml | 884 ++++++++++++++++++ .../test_DCHdigi/compact/materials_o1_v02.xml | 601 ++++++++++++ DCHdigi/test/{ => test_DCHdigi}/runDCHdigi.py | 4 +- DCHdigi/test/test_DCHdigi/sim_steering.py | 594 ++++++++++++ DCHdigi/test/test_DCHdigi/test_DCHdigi.sh | 19 + 8 files changed, 2333 insertions(+), 4 deletions(-) create mode 100644 DCHdigi/test/test_DCHdigi/check_DCHdigi_output.py create mode 100644 DCHdigi/test/test_DCHdigi/compact/DCH_standalone_o1_v02.xml create mode 100644 DCHdigi/test/test_DCHdigi/compact/elements_o1_v01.xml create mode 100644 DCHdigi/test/test_DCHdigi/compact/materials_o1_v02.xml rename DCHdigi/test/{ => test_DCHdigi}/runDCHdigi.py (94%) create mode 100644 DCHdigi/test/test_DCHdigi/sim_steering.py create mode 100644 DCHdigi/test/test_DCHdigi/test_DCHdigi.sh diff --git a/DCHdigi/include/DCHdigi.h b/DCHdigi/include/DCHdigi.h index 92e1c15..8bf2396 100644 --- a/DCHdigi/include/DCHdigi.h +++ b/DCHdigi/include/DCHdigi.h @@ -117,10 +117,10 @@ struct DCHdigi final // machinery for smearing the position /// along the sense wire position resolution in mm - Gaudi::Property m_z_resolution{this, "zResolution_mm", 10.0, + Gaudi::Property m_z_resolution{this, "zResolution_mm", 0.1, "Spatial resolution in the z direction (from reading out the wires at both sides) [mm]"}; /// xy resolution in mm - Gaudi::Property m_xy_resolution{this, "xyResolution_mm", 10., "Spatial resolution in the xy direction [mm]"}; + Gaudi::Property m_xy_resolution{this, "xyResolution_mm", 0.1, "Spatial resolution in the xy direction [mm]"}; /// create seed using the uid SmartIF m_uidSvc; diff --git a/DCHdigi/test/test_DCHdigi/check_DCHdigi_output.py b/DCHdigi/test/test_DCHdigi/check_DCHdigi_output.py new file mode 100644 index 0000000..afc58de --- /dev/null +++ b/DCHdigi/test/test_DCHdigi/check_DCHdigi_output.py @@ -0,0 +1,34 @@ +# file: check_DCHdigi_output.py +# author: Alvaro Tolosa-Delgado, CERN 2024 +# to run: python3 check_DCHdigi_output.py +# goal: check distance hit-wire and print out a number: +# 0 : calculation of distance hit-wire was done properly +# 1 : problem with calculation of distance hit-wire +# 2 : problem with calculation of hit-projection position onto the wire + +import ROOT + +exit_code=0 +# open debug output file generated by DCHdigi alg +f=ROOT.TFile("dch_digi_alg_debug.root") + +# retrieve the hit-wire distance distribution +hDpw=f.Get("hDpw") +hDpw.Rebin(10) +# retrieve the distance at which the distance distribution has its maximum +distance_hit_wire_more_frequent=hDpw.GetXaxis().GetBinCenter( hDpw.GetMaximumBin() ) +# the distance hit wire has the maximum around d=0.66cm +# if it is not the case, that means something weird is going on... +if 0.05 < abs(distance_hit_wire_more_frequent - 0.65) : + exit_code+=1 + +# retrieve the hit-projection onto the wire to the wire distance distribution +hDww=f.Get("hDww") +# since the hit-projection onto the wire should be a point on the wire, the distance should be zero +# and all the counts are pushed to the bin number 1 (which is excluded from the integral) +hDww_integral=hDww.Integral(2,-1) +if hDww_integral != 0 : + exit_code+=2 + +# we have to print the exit code, so it can be captured by the bash script +print(exit_code) diff --git a/DCHdigi/test/test_DCHdigi/compact/DCH_standalone_o1_v02.xml b/DCHdigi/test/test_DCHdigi/compact/DCH_standalone_o1_v02.xml new file mode 100644 index 0000000..8f48e4f --- /dev/null +++ b/DCHdigi/test/test_DCHdigi/compact/DCH_standalone_o1_v02.xml @@ -0,0 +1,197 @@ + + + + The compact format of the DCH subdetector, built from XLSX spreadsheet + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + system:5,superlayer:5,layer:4,nphi:11,stereosign:-1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DCHdigi/test/test_DCHdigi/compact/elements_o1_v01.xml b/DCHdigi/test/test_DCHdigi/compact/elements_o1_v01.xml new file mode 100644 index 0000000..f35eb34 --- /dev/null +++ b/DCHdigi/test/test_DCHdigi/compact/elements_o1_v01.xml @@ -0,0 +1,884 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DCHdigi/test/test_DCHdigi/compact/materials_o1_v02.xml b/DCHdigi/test/test_DCHdigi/compact/materials_o1_v02.xml new file mode 100644 index 0000000..189bc20 --- /dev/null +++ b/DCHdigi/test/test_DCHdigi/compact/materials_o1_v02.xml @@ -0,0 +1,601 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CMS ECAL https://gitlab.cern.ch/geant4/geant4/-/blob/master/examples/advanced/composite_calorimeter/dataglobal/material.cms#L183 + + + + + + + + + + + + + + + + 0.98810714*2.7 + 0.011892860*10.49 + + field wire center: 50 um Al (core), 0.3 um Ag (coating) + + + + + 0.98516708*2.7 + 0.014832922*10.49 + + field wires top/bottom: 40 um Al (core), 0.3 um Ag (coating) + + + + + 0.97066175*19.28+0.029338250*19.3 + + sense wire: 20 um W (core), 0.3 um Au (coating) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DCHdigi/test/runDCHdigi.py b/DCHdigi/test/test_DCHdigi/runDCHdigi.py similarity index 94% rename from DCHdigi/test/runDCHdigi.py rename to DCHdigi/test/test_DCHdigi/runDCHdigi.py index 0204bd0..07f3207 100644 --- a/DCHdigi/test/runDCHdigi.py +++ b/DCHdigi/test/test_DCHdigi/runDCHdigi.py @@ -22,8 +22,8 @@ DCHdigi.DCH_name="DCH_v2" DCHdigi.fileDataAlg="DataAlgFORGEANT.root" DCHdigi.create_debug_histograms=True -DCHdigi.zResolution_mm=1.23 -DCHdigi.xyResolution_mm=4.56 +DCHdigi.zResolution_mm=0.1 +DCHdigi.xyResolution_mm=0.1 DCHdigi.OutputLevel=INFO diff --git a/DCHdigi/test/test_DCHdigi/sim_steering.py b/DCHdigi/test/test_DCHdigi/sim_steering.py new file mode 100644 index 0000000..a0789e5 --- /dev/null +++ b/DCHdigi/test/test_DCHdigi/sim_steering.py @@ -0,0 +1,594 @@ +from DDSim.DD4hepSimulation import DD4hepSimulation +from g4units import mm, GeV, MeV +SIM = DD4hepSimulation() + +## The compact XML file, or multiple compact files, if the last one is the closer. +SIM.compactFile = ['compact/DCH_standalone_o1_v02.xml'] +## Lorentz boost for the crossing angle, in radian! +SIM.crossingAngleBoost = 0.0 +SIM.enableDetailedShowerMode = False +SIM.enableG4GPS = False +SIM.enableG4Gun = False +SIM.enableGun = True +## InputFiles for simulation .stdhep, .slcio, .HEPEvt, .hepevt, .pairs, .hepmc, .hepmc.gz, .hepmc.xz, .hepmc.bz2, .hepmc3, .hepmc3.gz, .hepmc3.xz, .hepmc3.bz2, .hepmc3.tree.root files are supported +SIM.inputFiles = [] +## Macro file to execute for runType 'run' or 'vis' +SIM.macroFile = "scripts/vis.mac" +## number of events to simulate, used in batch mode +SIM.numberOfEvents = 10 +## Outputfile from the simulation: .slcio, edm4hep.root and .root output files are supported +SIM.outputFile = "dch.root" +## Physics list to use in simulation +SIM.physicsList = None +## Verbosity use integers from 1(most) to 7(least) verbose +## or strings: VERBOSE, DEBUG, INFO, WARNING, ERROR, FATAL, ALWAYS +SIM.printLevel = 3 +## The type of action to do in this invocation +## batch: just simulate some events, needs numberOfEvents, and input file or gun +## vis: enable visualisation, run the macroFile if it is set +## qt: enable visualisation in Qt shell, run the macroFile if it is set +## run: run the macroFile and exit +## shell: enable interactive session +SIM.runType = "qt" +## Skip first N events when reading a file +SIM.skipNEvents = 0 +## Steering file to change default behaviour +SIM.steeringFile = None +## FourVector of translation for the Smearing of the Vertex position: x y z t +SIM.vertexOffset = [0.0, 0.0, 0.0, 0.0] +## FourVector of the Sigma for the Smearing of the Vertex position: x y z t +SIM.vertexSigma = [0.0, 0.0, 0.0, 0.0] + + +################################################################################ +## Helper holding sensitive detector and other actions. +## +## The default tracker and calorimeter sensitive actions can be set with +## +## >>> SIM = DD4hepSimulation() +## >>> SIM.action.tracker=('Geant4TrackerWeightedAction', {'HitPositionCombination': 2, 'CollectSingleDeposits': False}) +## >>> SIM.action.calo = "Geant4CalorimeterAction" +## +## The default sensitive actions for calorimeters and trackers are applied based on the sensitive type. +## The list of sensitive types can be changed with +## +## >>> SIM = DD4hepSimulation() +## >>> SIM.action.trackerSDTypes = ['tracker', 'myTrackerSensType'] +## >>> SIM.calor.calorimeterSDTypes = ['calorimeter', 'myCaloSensType'] +## +## For specific subdetectors specific sensitive detectors can be set based on patterns in the name of the subdetector. +## +## >>> SIM = DD4hepSimulation() +## >>> SIM.action.mapActions['tpc'] = "TPCSDAction" +## +## and additional parameters for the sensitive detectors can be set when the map is given a tuple +## +## >>> SIM = DD4hepSimulation() +## >>> SIM.action.mapActions['ecal'] =( "CaloPreShowerSDAction", {"FirstLayerNumber": 1} ) +## +## Additional actions can be set as well with the following syntax variations: +## +## >>> SIM = DD4hepSimulation() +## # single action by name only: +## >>> SIM.action.run = "Geant4TestRunAction" +## # multiple actions with comma-separated names: +## >>> SIM.action.event = "Geant4TestEventAction/Action0,Geant4TestEventAction/Action1" +## # single action by tuple of name and parameter dict: +## >>> SIM.action.track = ( "Geant4TestTrackAction", {"Property_int": 10} ) +## # single action by dict of name and parameter dict: +## >>> SIM.action.step = { "name": "Geant4TestStepAction", "parameter": {"Property_int": 10} } +## # multiple actions by list of dict of name and parameter dict: +## >>> SIM.action.stack = [ { "name": "Geant4TestStackAction", "parameter": {"Property_int": 10} } ] +## +## On the command line or in python, these actions can be specified as JSON strings: +## $ ddsim --action.stack '{ "name": "Geant4TestStackAction", "parameter": { "Property_int": 10 } }' +## or +## >>> SIM.action.stack = ''' +## { +## "name": "Geant4TestStackAction", +## "parameter": { +## "Property_int": 10, +## "Property_double": "1.0*mm" +## } +## } +## ''' +## +## +################################################################################ + +## set the default calorimeter action +SIM.action.calo = "Geant4ScintillatorCalorimeterAction" + +## List of patterns matching sensitive detectors of type Calorimeter. +SIM.action.calorimeterSDTypes = ['calorimeter'] + +## set the default event action +SIM.action.event = [] + +## Create a map of patterns and actions to be applied to sensitive detectors. +## +## Example: if the name of the detector matches 'tpc' the TPCSDAction is used. +## +## SIM.action.mapActions['tpc'] = "TPCSDAction" +## +SIM.action.mapActions = {} +SIM.action.mapActions['DCH_v2'] = "Geant4SimpleTrackerAction" + +## set the default run action +SIM.action.run = [] + +## set the default stack action +SIM.action.stack = [] + +## set the default step action +SIM.action.step = [] + +## set the default track action +SIM.action.track = [] + +## set the default tracker action +SIM.action.tracker = ('Geant4TrackerWeightedAction', {'HitPositionCombination': 2, 'CollectSingleDeposits': False}) + +## List of patterns matching sensitive detectors of type Tracker. +SIM.action.trackerSDTypes = ['tracker'] + + +################################################################################ +## Configuration for the magnetic field (stepper) +################################################################################ +SIM.field.delta_chord = 0.25 +SIM.field.delta_intersection = 0.001 +SIM.field.delta_one_step = 0.01 +SIM.field.eps_max = 0.001 +SIM.field.eps_min = 5e-05 +SIM.field.equation = "Mag_UsualEqRhs" +SIM.field.largest_step = 10000.0 +SIM.field.min_chord_step = 0.01 +SIM.field.stepper = "ClassicalRK4" + + +################################################################################ +## Configuration for sensitive detector filters +## +## Set the default filter for 'tracker' +## >>> SIM.filter.tracker = "edep1kev" +## Use no filter for 'calorimeter' by default +## >>> SIM.filter.calo = "" +## +## Assign a filter to a sensitive detector via pattern matching +## >>> SIM.filter.mapDetFilter['FTD'] = "edep1kev" +## +## Or more than one filter: +## >>> SIM.filter.mapDetFilter['FTD'] = ["edep1kev", "geantino"] +## +## Don't use the default filter or anything else: +## >>> SIM.filter.mapDetFilter['TPC'] = None ## or "" or [] +## +## Create a custom filter. The dictionary is used to instantiate the filter later on +## >>> SIM.filter.filters['edep3kev'] = dict(name="EnergyDepositMinimumCut/3keV", parameter={"Cut": 3.0*keV} ) +## +## +################################################################################ + +## +## default filter for calorimeter sensitive detectors; +## this is applied if no other filter is used for a calorimeter +## +SIM.filter.calo = "edep0" + +## list of filter objects: map between name and parameter dictionary +SIM.filter.filters = {} + +## a map between patterns and filter objects, using patterns to attach filters to sensitive detector +SIM.filter.mapDetFilter = {} + +## default filter for tracking sensitive detectors; this is applied if no other filter is used for a tracker +SIM.filter.tracker = None + + +################################################################################ +## Configuration for the Detector Construction. +################################################################################ +SIM.geometry.dumpGDML = "" +SIM.geometry.dumpHierarchy = 0 + +## Print Debug information about Elements +SIM.geometry.enableDebugElements = False + +## Print Debug information about Materials +SIM.geometry.enableDebugMaterials = False + +## Print Debug information about Placements +SIM.geometry.enableDebugPlacements = False + +## Print Debug information about Reflections +SIM.geometry.enableDebugReflections = False + +## Print Debug information about Regions +SIM.geometry.enableDebugRegions = False + +## Print Debug information about Shapes +SIM.geometry.enableDebugShapes = False + +## Print Debug information about Surfaces +SIM.geometry.enableDebugSurfaces = False + +## Print Debug information about Volumes +SIM.geometry.enableDebugVolumes = False + +## Print information about placements +SIM.geometry.enablePrintPlacements = False + +## Print information about Sensitives +SIM.geometry.enablePrintSensitives = False + + +################################################################################ +## Configuration for the GuineaPig InputFiles +################################################################################ + +## Set the number of pair particles to simulate per event. +## Only used if inputFile ends with ".pairs" +## If "-1" all particles will be simulated in a single event +## +SIM.guineapig.particlesPerEvent = "-1" + + +################################################################################ +## Configuration for the DDG4 ParticleGun +################################################################################ + +## direction of the particle gun, 3 vector +SIM.gun.direction = (0, 0, 1) + +## choose the distribution of the random direction for theta +## +## Options for random distributions: +## +## 'uniform' is the default distribution, flat in theta +## 'cos(theta)' is flat in cos(theta) +## 'eta', or 'pseudorapidity' is flat in pseudorapity +## 'ffbar' is distributed according to 1+cos^2(theta) +## +## Setting a distribution will set isotrop = True +## +SIM.gun.distribution = 'cos(theta)' + +## Total energy (including mass) for the particle gun. +## +## If not None, it will overwrite the setting of momentumMin and momentumMax +SIM.gun.energy = '10*GeV' + +## Maximal pseudorapidity for random distibution (overrides thetaMin) +SIM.gun.etaMax = None + +## Minimal pseudorapidity for random distibution (overrides thetaMax) +SIM.gun.etaMin = None + +## isotropic distribution for the particle gun +## +## use the options phiMin, phiMax, thetaMin, and thetaMax to limit the range of randomly distributed directions +## if one of these options is not None the random distribution will be set to True and cannot be turned off! +## +SIM.gun.isotrop = False + +## Maximal momentum when using distribution (default = 0.0) +SIM.gun.momentumMax = 10000.0 + +## Minimal momentum when using distribution (default = 0.0) +SIM.gun.momentumMin = 0.0 +SIM.gun.multiplicity = 1 +SIM.gun.particle = "proton" + +## Maximal azimuthal angle for random distribution +SIM.gun.phiMax = None + +## Minimal azimuthal angle for random distribution +SIM.gun.phiMin = None + +## position of the particle gun, 3 vector +SIM.gun.position = (0.0, 0.0, 0.0) + +## Maximal polar angle for random distribution +SIM.gun.thetaMax = None + +## Minimal polar angle for random distribution +SIM.gun.thetaMin = None + + +################################################################################ +## Configuration for the hepmc3 InputFiles +################################################################################ + +## Set the name of the attribute contraining color flow information index 0. +SIM.hepmc3.Flow1 = "flow1" + +## Set the name of the attribute contraining color flow information index 1. +SIM.hepmc3.Flow2 = "flow2" + +## Set to false if the input should be opened with the hepmc2 ascii reader. +## +## If ``True`` a '.hepmc' file will be opened with the HEPMC3 Reader Factory. +## +## Defaults to true if DD4hep was build with HEPMC3 support. +## +SIM.hepmc3.useHepMC3 = True + + +################################################################################ +## Configuration for Input Files. +################################################################################ + +## Set one or more functions to configure input steps. +## +## The functions must take a ``DD4hepSimulation`` object as their only argument and return the created generatorAction +## ``gen`` (for example). +## +## For example one can add this to the ddsim steering file: +## +## def exampleUserPlugin(dd4hepSimulation): +## '''Example code for user created plugin. +## +## :param DD4hepSimulation dd4hepSimulation: The DD4hepSimulation instance, so all parameters can be accessed +## :return: GeneratorAction +## ''' +## from DDG4 import GeneratorAction, Kernel +## # Geant4InputAction is the type of plugin, Cry1 just an identifier +## gen = GeneratorAction(Kernel(), 'Geant4InputAction/Cry1' , True) +## # CRYEventReader is the actual plugin, steeringFile its constructor parameter +## gen.Input = 'CRYEventReader|' + 'steeringFile' +## # we can give a dictionary of Parameters that has to be interpreted by the setParameters function of the plugin +## gen.Parameters = {'DataFilePath': '/path/to/files/data'} +## gen.enableUI() +## return gen +## +## SIM.inputConfig.userInputPlugin = exampleUserPlugin +## +## Repeat function definition and assignment to add multiple input steps +## +## +SIM.inputConfig.userInputPlugin = [] + + +################################################################################ +## Configuration for the generator-level InputFiles +################################################################################ + +## Set the name of the collection containing the MCParticle input. +## Default is "MCParticle". +## +SIM.lcio.mcParticleCollectionName = "MCParticle" + + +################################################################################ +## Configuration for the LCIO output file settings +################################################################################ + +## The event number offset to write in slcio output file. E.g setting it to 42 will start counting events from 42 instead of 0 +SIM.meta.eventNumberOffset = 0 + +## Event parameters to write in every event. Use C/F/I ids to specify parameter type. E.g parameterName/F=0.42 to set a float parameter +SIM.meta.eventParameters = [] + +## The run number offset to write in slcio output file. E.g setting it to 42 will start counting runs from 42 instead of 0 +SIM.meta.runNumberOffset = 0 + + +################################################################################ +## Configuration for the output levels of DDG4 components +################################################################################ + +## Output level for geometry. +SIM.output.geometry = 2 + +## Output level for input sources +SIM.output.inputStage = 3 + +## Output level for Geant4 kernel +SIM.output.kernel = 3 + +## Output level for ParticleHandler +SIM.output.part = 3 + +## Output level for Random Number Generator setup +SIM.output.random = 6 + + +################################################################################ +## Configuration for Output Files. +################################################################################ + +## Use the DD4HEP output plugin regardless of outputfilename. +SIM.outputConfig.forceDD4HEP = False + +## Use the EDM4HEP output plugin regardless of outputfilename. +SIM.outputConfig.forceEDM4HEP = False + +## Use the LCIO output plugin regardless of outputfilename. +SIM.outputConfig.forceLCIO = False + +## Set a function to configure the outputFile. +## +## The function must take a ``DD4hepSimulation`` object as its only argument and return ``None``. +## +## For example one can add this to the ddsim steering file: +## +## def exampleUserPlugin(dd4hepSimulation): +## '''Example code for user created plugin. +## +## :param DD4hepSimulation dd4hepSimulation: The DD4hepSimulation instance, so all parameters can be accessed +## :return: None +## ''' +## from DDG4 import EventAction, Kernel +## dd = dd4hepSimulation # just shorter variable name +## evt_root = EventAction(Kernel(), 'Geant4Output2ROOT/' + dd.outputFile, True) +## evt_root.HandleMCTruth = True or False +## evt_root.Control = True +## output = dd.outputFile +## if not dd.outputFile.endswith(dd.outputConfig.myExtension): +## output = dd.outputFile + dd.outputConfig.myExtension +## evt_root.Output = output +## evt_root.enableUI() +## Kernel().eventAction().add(evt_root) +## return None +## +## SIM.outputConfig.userOutputPlugin = exampleUserPlugin +## # arbitrary options can be created and set via the steering file or command line +## SIM.outputConfig.myExtension = '.csv' +## +SIM.outputConfig.userOutputPlugin = None + + +################################################################################ +## Configuration for the Particle Handler/ MCTruth treatment +################################################################################ + +## Enable lots of printout on simulated hits and MC-truth information +SIM.part.enableDetailedHitsAndParticleInfo = False + +## Keep all created particles +SIM.part.keepAllParticles = False + +## Minimal distance between particle vertex and endpoint of parent after +## which the vertexIsNotEndpointOfParent flag is set +## +SIM.part.minDistToParentVertex = 2.2e-14 + +## MinimalKineticEnergy to store particles created in the tracking region +SIM.part.minimalKineticEnergy = 1.0 + +## Printout at End of Tracking +SIM.part.printEndTracking = False + +## Printout at Start of Tracking +SIM.part.printStartTracking = False + +## List of processes to save, on command line give as whitespace separated string in quotation marks +SIM.part.saveProcesses = ['Decay'] + +## Optionally enable an extended Particle Handler +SIM.part.userParticleHandler = "Geant4TCUserParticleHandler" + + +################################################################################ +## Configuration for the PhysicsList and Monte Carlo particle selection. +## +## To load arbitrary plugins, add a function to be executed. +## +## The function must take the DDG4.Kernel() object as the only argument. +## +## For example, add a function definition and the call to a steering file:: +## +## def setupCerenkov(kernel): +## from DDG4 import PhysicsList +## seq = kernel.physicsList() +## cerenkov = PhysicsList(kernel, 'Geant4CerenkovPhysics/CerenkovPhys') +## cerenkov.MaxNumPhotonsPerStep = 10 +## cerenkov.MaxBetaChangePerStep = 10.0 +## cerenkov.TrackSecondariesFirst = True +## cerenkov.VerboseLevel = 2 +## cerenkov.enableUI() +## seq.adopt(cerenkov) +## ph = PhysicsList(kernel, 'Geant4OpticalPhotonPhysics/OpticalGammaPhys') +## ph.addParticleConstructor('G4OpticalPhoton') +## ph.VerboseLevel = 2 +## ph.enableUI() +## seq.adopt(ph) +## return None +## +## SIM.physics.setupUserPhysics(setupCerenkov) +## +## # End of example +## +################################################################################ + +## Set of Generator Statuses that are used to mark unstable particles that should decay inside of Geant4. +## +SIM.physics.alternativeDecayStatuses = set() + +## If true, add decay processes for all particles. +## +## Only enable when creating a physics list not based on an existing Geant4 list! +## +SIM.physics.decays = False + +## The name of the Geant4 Physics list. +SIM.physics.list = "FTFP_BERT" + +## location of particle.tbl file containing extra particles and their lifetime information +## +## For example in $DD4HEP/examples/DDG4/examples/particle.tbl +## +SIM.physics.pdgfile = None + +## The global geant4 rangecut for secondary production +## +## Default is 0.7 mm as is the case in geant4 10 +## +## To disable this plugin and be absolutely sure to use the Geant4 default range cut use "None" +## +## Set printlevel to DEBUG to see a printout of all range cuts, +## but this only works if range cut is not "None" +## +SIM.physics.rangecut = 0.7 + +## Set of PDG IDs that will not be passed from the input record to Geant4. +## +## Quarks, gluons and W's Z's etc should not be treated by Geant4 +## +SIM.physics.rejectPDGs = {1, 2, 3, 4, 5, 6, 3201, 3203, 4101, 4103, 21, 23, 24, 5401, 25, 2203, 5403, 3101, 3103, 4403, 2101, 5301, 2103, 5303, 4301, 1103, 4303, 5201, 5203, 3303, 4201, 4203, 5101, 5103, 5503} + +## Set of PDG IDs for particles that should not be passed to Geant4 if their properTime is 0. +## +## The properTime of 0 indicates a documentation to add FSR to a lepton for example. +## +SIM.physics.zeroTimePDGs = {17, 11, 13, 15} + + +################################################################################ +## Properties for the random number generator +################################################################################ + +## If True, calculate random seed for each event basedon eventID and runID +## Allows reproducibility even whenSkippingEvents +SIM.random.enableEventSeed = False +SIM.random.file = None +SIM.random.luxury = 1 +SIM.random.replace_gRandom = True +SIM.random.seed = None +SIM.random.type = None + + +################################################################################ +## Configuration for setting commands to run during different phases. +## +## In this section, one can configure commands that should be run during the different phases of the Geant4 execution. +## +## 1. Configuration +## 2. Initialization +## 3. Pre Run +## 4. Post Run +## 5. Terminate / Finalization +## +## For example, one can add +## +## >>> SIM.ui.commandsConfigure = ['/physics_lists/em/SyncRadiation true'] +## +## Further details should be taken from the Geant4 documentation. +## +################################################################################ + +## List of UI commands to run during the 'Configure' phase. +SIM.ui.commandsConfigure = [] + +## List of UI commands to run during the 'Initialize' phase. +SIM.ui.commandsInitialize = [] + +## List of UI commands to run during the 'PostRun' phase. +SIM.ui.commandsPostRun = [] + +## List of UI commands to run during the 'PreRun' phase. +SIM.ui.commandsPreRun = [] + +## List of UI commands to run during the 'Terminate' phase. +SIM.ui.commandsTerminate = [] diff --git a/DCHdigi/test/test_DCHdigi/test_DCHdigi.sh b/DCHdigi/test/test_DCHdigi/test_DCHdigi.sh new file mode 100644 index 0000000..8327e40 --- /dev/null +++ b/DCHdigi/test/test_DCHdigi/test_DCHdigi.sh @@ -0,0 +1,19 @@ +# file: test_DCHdigi.sh +# author: Alvaro Tolosa-Delgado, CERN 2024 +# to run: sh + test_DCHdigi.sh +# goal: run sim-digitizer of the DCH v2, and return code printed by check_DCHdigi_output.py + +# run simulation with the drift chamber alone +ddsim --steeringFile sim_steering.py --outputFile 'dch_proton_10GeV.root' -N 10 --runType batch --random.seed 42 + +# download file for cluster counting technique +wget https://fccsw.web.cern.ch/fccsw/filesForSimDigiReco/IDEA/DataAlgFORGEANT.root + +# run digitizer for position smearing and cluster counting calculation +k4run runDCHdigi.py + +# check distribution of distance from hit position to the wire +check_DCHdigi_output=$( (python3 check_DCHdigi_output.py) 2>&1) + +# return value printed out by the previous python script +exit $check_DCHdigi_output From bd8a6560622e98de22694b488a8df389a86a18d9 Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Fri, 9 Aug 2024 15:41:09 +0200 Subject: [PATCH 08/56] add protection in case the file for CLS is not available --- DCHdigi/test/test_DCHdigi/test_DCHdigi.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/DCHdigi/test/test_DCHdigi/test_DCHdigi.sh b/DCHdigi/test/test_DCHdigi/test_DCHdigi.sh index 8327e40..572f5ff 100644 --- a/DCHdigi/test/test_DCHdigi/test_DCHdigi.sh +++ b/DCHdigi/test/test_DCHdigi/test_DCHdigi.sh @@ -7,7 +7,14 @@ ddsim --steeringFile sim_steering.py --outputFile 'dch_proton_10GeV.root' -N 10 --runType batch --random.seed 42 # download file for cluster counting technique -wget https://fccsw.web.cern.ch/fccsw/filesForSimDigiReco/IDEA/DataAlgFORGEANT.root +ifilename="https://fccsw.web.cern.ch/fccsw/filesForSimDigiReco/IDEA/DataAlgFORGEANT.root" +wget $ifilename + +# Check if the input file exists +if [[ ! -f "$(basename $ifilename)" ]]; then + echo "Error: File '$(basename $ifilename)' not found." + exit 1 +fi # run digitizer for position smearing and cluster counting calculation k4run runDCHdigi.py From eff7cbb33e2ece02f6a6818c8d00335d02855b75 Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Fri, 9 Aug 2024 15:41:15 +0200 Subject: [PATCH 09/56] add ctest --- DCHdigi/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/DCHdigi/CMakeLists.txt b/DCHdigi/CMakeLists.txt index 0f6fd62..d34d7d3 100644 --- a/DCHdigi/CMakeLists.txt +++ b/DCHdigi/CMakeLists.txt @@ -97,3 +97,8 @@ set_test_env(${test_name}) SET(test_name "test_DCHsimpleDigitizerExtendedEdm") ADD_TEST(NAME ${test_name} COMMAND k4run test/runDCHsimpleDigitizerExtendedEdm.py) set_test_env(${test_name}) + +SET(test_name "test_runDCHdigiV2") +ADD_TEST(NAME ${test_name} COMMAND sh +x test_DCHdigi.sh ) +set_test_env(${test_name}) +set_tests_properties(${test_name} PROPERTIES WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/DCHdigi/test/test_DCHdigi") From 7ea07c2b7bf659f0234d3210b4569abf112dba57 Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Fri, 9 Aug 2024 16:11:02 +0200 Subject: [PATCH 10/56] cast variables to void to get rid of spurious compiler warning --- DCHdigi/src/DCHdigi.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/DCHdigi/src/DCHdigi.cpp b/DCHdigi/src/DCHdigi.cpp index 98fcb5b..bba91d8 100644 --- a/DCHdigi/src/DCHdigi.cpp +++ b/DCHdigi/src/DCHdigi.cpp @@ -403,6 +403,12 @@ std::pair DCHdigi::CalculateClusters(const edm4hep::SimTracke std::vector vecEtr,vecEtrTot; float sumVecTot,meanVecTot,sumVec,meanVec; /////////end from Createclusters.h///////// + + // get rid of spurious compiler error, Werror=unused-but-set-variable + (void)NCl; + (void)vecpar; + (void)sumVecTot; + int NCld; TString parName; double bg, Momentum, mass=-1e300; From af01cbe6cd27e3ef3f4042f003e6625cc0afeb11 Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Mon, 12 Aug 2024 10:34:15 +0200 Subject: [PATCH 11/56] add edm4hep link in yaml --- DCHdigi/dataFormatExtension/driftChamberHit.yaml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/DCHdigi/dataFormatExtension/driftChamberHit.yaml b/DCHdigi/dataFormatExtension/driftChamberHit.yaml index d934d3b..228668e 100644 --- a/DCHdigi/dataFormatExtension/driftChamberHit.yaml +++ b/DCHdigi/dataFormatExtension/driftChamberHit.yaml @@ -34,6 +34,15 @@ datatypes: - float eDepError // error measured on eDep [GeV]. - uint32_t clusterCount // number of clusters associated to this hit + extension::MCRecoDriftChamberDigiAssociation: + Description: "Association between a DriftChamberDigi and the corresponding simulated hit" + Author: "B. Francois, CERN" + Members: + - float weight // weight of this association + OneToOneRelations: + - extension::DriftChamberDigi digi // reference to the digitized hit + - edm4hep::SimTrackerHit sim // reference to the simulated hit + extension::DriftChamberDigiV2: Description: "Digitized hit (before tracking) for Drift Chamber v2 (requires data extension)." Author: "A. Tolosa-Delgado, B. Francois, CERN" @@ -50,11 +59,11 @@ datatypes: - uint32_t clusterCount // number of clusters associated to this hit - uint32_t clusterSize // number of electrons per cluster - extension::MCRecoDriftChamberDigiAssociation: + extension::MCRecoDriftChamberDigiV2Association: Description: "Association between a DriftChamberDigi and the corresponding simulated hit" Author: "B. Francois, CERN" Members: - float weight // weight of this association OneToOneRelations: - - extension::DriftChamberDigi digi // reference to the digitized hit + - extension::DriftChamberDigiV2 digi // reference to the digitized hit - edm4hep::SimTrackerHit sim // reference to the simulated hit From 715534d60dac6cbf7942a6d70608a33c48988bd9 Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Mon, 12 Aug 2024 11:16:46 +0200 Subject: [PATCH 12/56] use to mutable digi hit --- DCHdigi/src/DCHdigi.cpp | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/DCHdigi/src/DCHdigi.cpp b/DCHdigi/src/DCHdigi.cpp index bba91d8..49b879f 100644 --- a/DCHdigi/src/DCHdigi.cpp +++ b/DCHdigi/src/DCHdigi.cpp @@ -4,6 +4,8 @@ #include #include +#include "extension/MutableDriftChamberDigiV2.h" + /////////////////////////////////////////////////////////////////////////////////////// /////////////////////// DCHdigi constructor //////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// @@ -158,19 +160,20 @@ DCHdigi::operator()(const colltype_in& input_sim_hits, auto [clusterCount,clusterSize] = CalculateClusters(input_sim_hit); - // create in place the output object - output_digi_hits.create(input_sim_hit.getCellID(), - type, - quality, - input_sim_hit.getTime(), - input_sim_hit.getEDep(), - eDepError, - positionSW, - directionSW, - distanceToWire, - clusterCount, - clusterSize - ); + extension::MutableDriftChamberDigiV2 oDCHdigihit; + oDCHdigihit.setCellID(input_sim_hit.getCellID()); + oDCHdigihit.setType(type); + oDCHdigihit.setQuality(quality); + oDCHdigihit.setTime(input_sim_hit.getTime()); + oDCHdigihit.setEDep(input_sim_hit.getEDep()); + oDCHdigihit.setEDepError(eDepError); + oDCHdigihit.setPosition(positionSW); + oDCHdigihit.setDirectionSW(directionSW); + oDCHdigihit.setDistanceToWire(distanceToWire); + oDCHdigihit.setClusterCount(clusterCount); + oDCHdigihit.setClusterSize(clusterSize); + + output_digi_hits.push_back(oDCHdigihit); }// end loop over hit collection ///////////////////////////////////////////////////////////////// From 5b33de04655280a96957700e5f6d97a1f81299fe Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Mon, 12 Aug 2024 11:27:23 +0200 Subject: [PATCH 13/56] add association as second collection in the output --- DCHdigi/include/DCHdigi.h | 7 +++++-- DCHdigi/src/DCHdigi.cpp | 13 ++++++++++--- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/DCHdigi/include/DCHdigi.h b/DCHdigi/include/DCHdigi.h index 8bf2396..b59978d 100644 --- a/DCHdigi/include/DCHdigi.h +++ b/DCHdigi/include/DCHdigi.h @@ -50,6 +50,7 @@ // EDM4HEP extension #include "extension/DriftChamberDigiV2Collection.h" +#include "extension/MCRecoDriftChamberDigiV2AssociationCollection.h" // DD4hep @@ -77,17 +78,19 @@ constexpr double MM_TO_CM = 0.1; using colltype_in = edm4hep::SimTrackerHitCollection; using colltype_out = extension::DriftChamberDigiV2Collection; +using colltype_out2= extension::MCRecoDriftChamberDigiV2AssociationCollection; + struct DCHdigi final : k4FWCore::MultiTransformer< - std::tuple( + std::tuple( const colltype_in&, const edm4hep::EventHeaderCollection&)> { DCHdigi(const std::string& name, ISvcLocator* svcLoc); StatusCode initialize() override; StatusCode finalize() override; - std::tuple operator()( + std::tuple operator()( const colltype_in& , const edm4hep::EventHeaderCollection& ) const override; diff --git a/DCHdigi/src/DCHdigi.cpp b/DCHdigi/src/DCHdigi.cpp index 49b879f..bff89f5 100644 --- a/DCHdigi/src/DCHdigi.cpp +++ b/DCHdigi/src/DCHdigi.cpp @@ -17,7 +17,8 @@ DCHdigi::DCHdigi(const std::string& name, ISvcLocator* svcLoc) KeyValues("HeaderName", {"EventHeader"}), }, { - KeyValues("DCH_DigiCollection", {"DCH_DigiCollection"}) + KeyValues("DCH_DigiCollection", {"DCH_DigiCollection"}), + KeyValues("DCH_DigiSimAssociationCollection", {"DCH_DigiSimAssociationCollection"}) } ) { @@ -96,7 +97,7 @@ StatusCode DCHdigi::initialize() { /////////////////////////////////////////////////////////////////////////////////////// /////////////////////// operator() //////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// -std::tuple +std::tuple DCHdigi::operator()(const colltype_in& input_sim_hits, const edm4hep::EventHeaderCollection& headers) const { @@ -107,6 +108,7 @@ DCHdigi::operator()(const colltype_in& input_sim_hits, // Create the collections we are going to return colltype_out output_digi_hits; + colltype_out2 output_digi_sim_association; //loop over hit collection for (const auto& input_sim_hit : input_sim_hits) @@ -174,10 +176,15 @@ DCHdigi::operator()(const colltype_in& input_sim_hits, oDCHdigihit.setClusterSize(clusterSize); output_digi_hits.push_back(oDCHdigihit); + + extension::MutableMCRecoDriftChamberDigiV2Association oDCHsimdigi_association; + oDCHsimdigi_association.setDigi( output_digi_hits.at( output_digi_hits.size() ) ); + oDCHsimdigi_association.setSim( input_sim_hit ); + }// end loop over hit collection ///////////////////////////////////////////////////////////////// - return std::make_tuple(std::move(output_digi_hits)); + return std::make_tuple(std::move(output_digi_hits),std::move(output_digi_sim_association)); } /////////////////////////////////////////////////////////////////////////////////////// From 44485a19f31bbb85a2f24a91be7e8f7447e70717 Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Mon, 12 Aug 2024 11:34:26 +0200 Subject: [PATCH 14/56] fix path to compact file of DCH stand alone --- DCHdigi/test/test_DCHdigi/runDCHdigi.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DCHdigi/test/test_DCHdigi/runDCHdigi.py b/DCHdigi/test/test_DCHdigi/runDCHdigi.py index 07f3207..05ba355 100644 --- a/DCHdigi/test/test_DCHdigi/runDCHdigi.py +++ b/DCHdigi/test/test_DCHdigi/runDCHdigi.py @@ -14,7 +14,7 @@ from Configurables import GeoSvc geoservice = GeoSvc("GeoSvc") -geoservice.detectors = ['/home/alvarotd/work/mydch/DCH_detector/compact/DCH_standalone_o1_v02.xml'] +geoservice.detectors = ['./compact/DCH_standalone_o1_v02.xml'] from Configurables import DCHdigi DCHdigi = DCHdigi("DCHdigi") From 98ccbad0ad3d59e2305fc387cd026b6ab16c31a0 Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Mon, 12 Aug 2024 11:56:34 +0200 Subject: [PATCH 15/56] array index in C start at 0... --- DCHdigi/src/DCHdigi.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DCHdigi/src/DCHdigi.cpp b/DCHdigi/src/DCHdigi.cpp index bff89f5..03c5f5c 100644 --- a/DCHdigi/src/DCHdigi.cpp +++ b/DCHdigi/src/DCHdigi.cpp @@ -178,7 +178,7 @@ DCHdigi::operator()(const colltype_in& input_sim_hits, output_digi_hits.push_back(oDCHdigihit); extension::MutableMCRecoDriftChamberDigiV2Association oDCHsimdigi_association; - oDCHsimdigi_association.setDigi( output_digi_hits.at( output_digi_hits.size() ) ); + oDCHsimdigi_association.setDigi( output_digi_hits.at( output_digi_hits.size()-1 ) ); oDCHsimdigi_association.setSim( input_sim_hit ); }// end loop over hit collection From 7c5ad810aa4d758e60af116b7f704ef06a7dce83 Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Mon, 12 Aug 2024 12:24:06 +0200 Subject: [PATCH 16/56] use ref to mutable object, to be checked if association is correct --- DCHdigi/src/DCHdigi.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DCHdigi/src/DCHdigi.cpp b/DCHdigi/src/DCHdigi.cpp index 03c5f5c..820fe7b 100644 --- a/DCHdigi/src/DCHdigi.cpp +++ b/DCHdigi/src/DCHdigi.cpp @@ -178,7 +178,7 @@ DCHdigi::operator()(const colltype_in& input_sim_hits, output_digi_hits.push_back(oDCHdigihit); extension::MutableMCRecoDriftChamberDigiV2Association oDCHsimdigi_association; - oDCHsimdigi_association.setDigi( output_digi_hits.at( output_digi_hits.size()-1 ) ); + oDCHsimdigi_association.setDigi( oDCHdigihit ); oDCHsimdigi_association.setSim( input_sim_hit ); }// end loop over hit collection From cc5dc9cf36d2a50a351ada8995a84e32c5f4c60a Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Fri, 23 Aug 2024 13:11:03 +0200 Subject: [PATCH 17/56] write association in the output --- DCHdigi/src/DCHdigi.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/DCHdigi/src/DCHdigi.cpp b/DCHdigi/src/DCHdigi.cpp index 820fe7b..c40cf57 100644 --- a/DCHdigi/src/DCHdigi.cpp +++ b/DCHdigi/src/DCHdigi.cpp @@ -180,6 +180,7 @@ DCHdigi::operator()(const colltype_in& input_sim_hits, extension::MutableMCRecoDriftChamberDigiV2Association oDCHsimdigi_association; oDCHsimdigi_association.setDigi( oDCHdigihit ); oDCHsimdigi_association.setSim( input_sim_hit ); + output_digi_sim_association.push_back(oDCHsimdigi_association); }// end loop over hit collection From eaf05253b04d4d543e62219c12888e47d79b4343 Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Fri, 23 Aug 2024 13:14:46 +0200 Subject: [PATCH 18/56] default z resolution 1 mm --- DCHdigi/include/DCHdigi.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/DCHdigi/include/DCHdigi.h b/DCHdigi/include/DCHdigi.h index b59978d..5fa95df 100644 --- a/DCHdigi/include/DCHdigi.h +++ b/DCHdigi/include/DCHdigi.h @@ -19,7 +19,7 @@ * @param fileDataAlg File needed for calculating cluster count and size
* (default value /eos/.../DataAlgFORGEANT.root)
* @param zResolution_mm Resolution (sigma for gaussian smearing) along the sense wire, in mm
- * (default value 10 mm)
+ * (default value 1 mm)
* @param xyResolution_mm Resolution (sigma for gaussian smearing) perpendicular the sense wire, in mm
* (default value 10 mm)
* @param create_debug_histograms Optional flag to create debug histograms
@@ -120,8 +120,8 @@ struct DCHdigi final // machinery for smearing the position /// along the sense wire position resolution in mm - Gaudi::Property m_z_resolution{this, "zResolution_mm", 0.1, - "Spatial resolution in the z direction (from reading out the wires at both sides) [mm]"}; + Gaudi::Property m_z_resolution{this, "zResolution_mm", 1.0, + "Spatial resolution in the z direction (from reading out the wires at both sides) in mm. Default 1 mm."}; /// xy resolution in mm Gaudi::Property m_xy_resolution{this, "xyResolution_mm", 0.1, "Spatial resolution in the xy direction [mm]"}; From 119fc631127f63444d16b16aa76bc23e14607b77 Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Fri, 23 Aug 2024 13:15:47 +0200 Subject: [PATCH 19/56] default xy resolution 0.1 mm --- DCHdigi/include/DCHdigi.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DCHdigi/include/DCHdigi.h b/DCHdigi/include/DCHdigi.h index 5fa95df..e7556d9 100644 --- a/DCHdigi/include/DCHdigi.h +++ b/DCHdigi/include/DCHdigi.h @@ -21,7 +21,7 @@ * @param zResolution_mm Resolution (sigma for gaussian smearing) along the sense wire, in mm
* (default value 1 mm)
* @param xyResolution_mm Resolution (sigma for gaussian smearing) perpendicular the sense wire, in mm
- * (default value 10 mm)
+ * (default value 0.1 mm)
* @param create_debug_histograms Optional flag to create debug histograms
* (default value false)
* @param GeoSvcName Geometry service name
@@ -123,7 +123,7 @@ struct DCHdigi final Gaudi::Property m_z_resolution{this, "zResolution_mm", 1.0, "Spatial resolution in the z direction (from reading out the wires at both sides) in mm. Default 1 mm."}; /// xy resolution in mm - Gaudi::Property m_xy_resolution{this, "xyResolution_mm", 0.1, "Spatial resolution in the xy direction [mm]"}; + Gaudi::Property m_xy_resolution{this, "xyResolution_mm", 0.1, "Spatial resolution in the xy direction in mm. Default 0.1 mm."}; /// create seed using the uid SmartIF m_uidSvc; From 1d488d46c9dd46afe1b04c25993d799d0f54b5a2 Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Fri, 23 Aug 2024 13:17:24 +0200 Subject: [PATCH 20/56] expanded comment about the uid service --- DCHdigi/include/DCHdigi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DCHdigi/include/DCHdigi.h b/DCHdigi/include/DCHdigi.h index e7556d9..e9abfc0 100644 --- a/DCHdigi/include/DCHdigi.h +++ b/DCHdigi/include/DCHdigi.h @@ -26,7 +26,7 @@ * (default value false)
* @param GeoSvcName Geometry service name
* (default value GeoSvc)
- * @param uidSvcName The name of the UniqueIDGenSvc instance
+ * @param uidSvcName The name of the UniqueIDGenSvc instance, used to create seed for each event/run, ensuring reproducibility.
* (default value uidSvc)
*
*/ From b4724245692b0c17624a496d8c8d0e54accb3b7e Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Fri, 23 Aug 2024 13:35:03 +0200 Subject: [PATCH 21/56] comment added --- DCHdigi/src/DCHdigi.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DCHdigi/src/DCHdigi.cpp b/DCHdigi/src/DCHdigi.cpp index c40cf57..e662e39 100644 --- a/DCHdigi/src/DCHdigi.cpp +++ b/DCHdigi/src/DCHdigi.cpp @@ -65,7 +65,7 @@ StatusCode DCHdigi::initialize() { m_decoder = dch_readout.idSpec().decoder(); /////////////////////////////////////////////////////////////////////////////////// - ///////////////////////// initialize Walaa's code for CLS /////////////////////// + ////////////////// initialize Walaa's code for Cluster counting ///////////////// /////////////////////////////////////////////////////////////////////////////////// debug() << Form("Opening %s...",m_fileDataAlg.value().c_str())<> not found."); From af864ff2756ee2836ac271cc70a1f4909c0f78e1 Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Fri, 23 Aug 2024 14:06:31 +0200 Subject: [PATCH 22/56] add comment about advancing the random engines --- DCHdigi/src/DCHdigi.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DCHdigi/src/DCHdigi.cpp b/DCHdigi/src/DCHdigi.cpp index e662e39..ae2740e 100644 --- a/DCHdigi/src/DCHdigi.cpp +++ b/DCHdigi/src/DCHdigi.cpp @@ -237,9 +237,9 @@ void DCHdigi::PrepareRandomEngine(const edm4hep::EventHeaderCollection& headers uint32_t run_n = headers[0].getRunNumber(); size_t seed = m_uidSvc->getUniqueID(evt_n, run_n, this->name() ); m_engine.seed(seed); - // test random engine... + // advance internal state to minimize possibility of creating correlations m_engine.discard(10); - myRandom.SetSeed(seed+42); + for(int i=0; i<10; ++i) myRandom.Rndm(); } /////////////////////////////////////////////////////////////////////////////////////// From a3780d97b266aede014ebff361cd4cbb7361abd5 Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Fri, 23 Aug 2024 14:12:14 +0200 Subject: [PATCH 23/56] change value in test --- DCHdigi/test/test_DCHdigi/runDCHdigi.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DCHdigi/test/test_DCHdigi/runDCHdigi.py b/DCHdigi/test/test_DCHdigi/runDCHdigi.py index 05ba355..8a59ade 100644 --- a/DCHdigi/test/test_DCHdigi/runDCHdigi.py +++ b/DCHdigi/test/test_DCHdigi/runDCHdigi.py @@ -22,7 +22,7 @@ DCHdigi.DCH_name="DCH_v2" DCHdigi.fileDataAlg="DataAlgFORGEANT.root" DCHdigi.create_debug_histograms=True -DCHdigi.zResolution_mm=0.1 +DCHdigi.zResolution_mm=1 DCHdigi.xyResolution_mm=0.1 From f289d0b15ad513e82e479b443d7bdc1dd9114af0 Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Fri, 23 Aug 2024 14:15:56 +0200 Subject: [PATCH 24/56] output file with histograms for debugging is now configurable from steering --- DCHdigi/include/DCHdigi.h | 4 +++- DCHdigi/src/DCHdigi.cpp | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/DCHdigi/include/DCHdigi.h b/DCHdigi/include/DCHdigi.h index e9abfc0..f94c112 100644 --- a/DCHdigi/include/DCHdigi.h +++ b/DCHdigi/include/DCHdigi.h @@ -191,7 +191,9 @@ struct DCHdigi final /// Flag to create output file with debug histgrams Gaudi::Property m_create_debug_histos{this, "create_debug_histograms", false, "Create output file with histograms for debugging"}; - + + /// name for the file that will contain the histograms for debugging + Gaudi::Property m_out_debug_filename{this, "out_debug_filename", "dch_digi_alg_debug.root", "name for the file that will contain the histograms for debugging"}; /// histogram to store distance from hit position to the wire TH1D * hDpw; diff --git a/DCHdigi/src/DCHdigi.cpp b/DCHdigi/src/DCHdigi.cpp index ae2740e..12b101f 100644 --- a/DCHdigi/src/DCHdigi.cpp +++ b/DCHdigi/src/DCHdigi.cpp @@ -195,7 +195,7 @@ StatusCode DCHdigi::finalize() { if( m_create_debug_histos.value() ) { - std::unique_ptr ofile{TFile::Open ( "dch_digi_alg_debug.root", "recreate" ) }; + std::unique_ptr ofile{TFile::Open ( m_out_debug_filename.value().c_str() , "recreate" ) }; ofile->cd(); hDpw->Write(); hDww->Write(); From 520d20672b34ffe129c6d254c2377e65f5f57c61 Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Fri, 23 Aug 2024 14:18:15 +0200 Subject: [PATCH 25/56] remove unused function --- DCHdigi/include/DCHdigi.h | 1 - DCHdigi/src/DCHdigi.cpp | 8 -------- 2 files changed, 9 deletions(-) diff --git a/DCHdigi/include/DCHdigi.h b/DCHdigi/include/DCHdigi.h index f94c112..317c3e3 100644 --- a/DCHdigi/include/DCHdigi.h +++ b/DCHdigi/include/DCHdigi.h @@ -172,7 +172,6 @@ struct DCHdigi final TVector3 Calculate_wire_z0_point (int ilayer, int nphi) const; double Calculate_wire_phi_z0 (int ilayer, int nphi) const; - double Calculate_phi_rot_equivalent_to_hit_to_wire_distance(int ilayer, double hit_to_wire_distance) const; //------------------------------------------------------------------ // cluster calculation, developed by Walaa diff --git a/DCHdigi/src/DCHdigi.cpp b/DCHdigi/src/DCHdigi.cpp index 12b101f..0e2f15e 100644 --- a/DCHdigi/src/DCHdigi.cpp +++ b/DCHdigi/src/DCHdigi.cpp @@ -246,14 +246,6 @@ void DCHdigi::PrepareRandomEngine(const edm4hep::EventHeaderCollection& headers ///// Ancillary functions for calculating the distance to the wire //////// /////////////////////////////////////////////////////////////////////////////////////// -double DCHdigi::Calculate_phi_rot_equivalent_to_hit_to_wire_distance(int ilayer, double hit_to_wire_distance) const -{ - auto & l = this->dch_data->database.at(ilayer); - double rz0 = l.radius_sw_z0; - return 2*atan( (hit_to_wire_distance/2.)/rz0 ); -} - - TVector3 DCHdigi::Calculate_wire_vector_ez(int ilayer, int nphi) const { From a9ff6893cbb2938b83491bb5194aa205234320a1 Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Fri, 23 Aug 2024 14:23:23 +0200 Subject: [PATCH 26/56] add shebang --- DCHdigi/test/test_DCHdigi/test_DCHdigi.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/DCHdigi/test/test_DCHdigi/test_DCHdigi.sh b/DCHdigi/test/test_DCHdigi/test_DCHdigi.sh index 572f5ff..f218ccd 100644 --- a/DCHdigi/test/test_DCHdigi/test_DCHdigi.sh +++ b/DCHdigi/test/test_DCHdigi/test_DCHdigi.sh @@ -1,3 +1,4 @@ +#!/bin/bash # file: test_DCHdigi.sh # author: Alvaro Tolosa-Delgado, CERN 2024 # to run: sh + test_DCHdigi.sh From f245c1541dd5e0e4d8547fa1fce7e4ca9050bc7c Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Fri, 23 Aug 2024 14:37:03 +0200 Subject: [PATCH 27/56] remove alias for edm4hep classes --- DCHdigi/include/DCHdigi.h | 13 ++++--------- DCHdigi/src/DCHdigi.cpp | 10 +++++----- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/DCHdigi/include/DCHdigi.h b/DCHdigi/include/DCHdigi.h index 317c3e3..1a438db 100644 --- a/DCHdigi/include/DCHdigi.h +++ b/DCHdigi/include/DCHdigi.h @@ -76,22 +76,17 @@ /// constant to convert from mm (EDM4hep) to DD4hep (cm) constexpr double MM_TO_CM = 0.1; -using colltype_in = edm4hep::SimTrackerHitCollection; -using colltype_out = extension::DriftChamberDigiV2Collection; -using colltype_out2= extension::MCRecoDriftChamberDigiV2AssociationCollection; - - struct DCHdigi final : k4FWCore::MultiTransformer< - std::tuple( - const colltype_in&, const edm4hep::EventHeaderCollection&)> { + std::tuple( + const edm4hep::SimTrackerHitCollection&, const edm4hep::EventHeaderCollection&)> { DCHdigi(const std::string& name, ISvcLocator* svcLoc); StatusCode initialize() override; StatusCode finalize() override; - std::tuple operator()( - const colltype_in& , + std::tuple operator()( + const edm4hep::SimTrackerHitCollection& , const edm4hep::EventHeaderCollection& ) const override; private: diff --git a/DCHdigi/src/DCHdigi.cpp b/DCHdigi/src/DCHdigi.cpp index 0e2f15e..5e00be4 100644 --- a/DCHdigi/src/DCHdigi.cpp +++ b/DCHdigi/src/DCHdigi.cpp @@ -97,8 +97,8 @@ StatusCode DCHdigi::initialize() { /////////////////////////////////////////////////////////////////////////////////////// /////////////////////// operator() //////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// -std::tuple -DCHdigi::operator()(const colltype_in& input_sim_hits, +std::tuple +DCHdigi::operator()(const edm4hep::SimTrackerHitCollection& input_sim_hits, const edm4hep::EventHeaderCollection& headers) const { // initialize seed for random engine @@ -107,8 +107,8 @@ DCHdigi::operator()(const colltype_in& input_sim_hits, debug() << "Input Sim Hit collection size: " << input_sim_hits.size() << endmsg; // Create the collections we are going to return - colltype_out output_digi_hits; - colltype_out2 output_digi_sim_association; + extension::DriftChamberDigiV2Collection output_digi_hits; + extension::MCRecoDriftChamberDigiV2AssociationCollection output_digi_sim_association; //loop over hit collection for (const auto& input_sim_hit : input_sim_hits) @@ -185,7 +185,7 @@ DCHdigi::operator()(const colltype_in& input_sim_hits, }// end loop over hit collection ///////////////////////////////////////////////////////////////// - return std::make_tuple(std::move(output_digi_hits),std::move(output_digi_sim_association)); + return std::make_tuple(std::move(output_digi_hits),std::move(output_digi_sim_association)); } /////////////////////////////////////////////////////////////////////////////////////// From 58445a262394a27663f2404c3d06726442a9a632 Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Fri, 23 Aug 2024 14:47:48 +0200 Subject: [PATCH 28/56] rename namespace of edm4hep extension to edm4hep, add interface --- .../dataFormatExtension/driftChamberHit.yaml | 23 ++++++++++++++++--- DCHdigi/include/DCHdigi.h | 4 ++-- DCHdigi/src/DCHdigi.cpp | 12 +++++----- 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/DCHdigi/dataFormatExtension/driftChamberHit.yaml b/DCHdigi/dataFormatExtension/driftChamberHit.yaml index 228668e..fd42930 100644 --- a/DCHdigi/dataFormatExtension/driftChamberHit.yaml +++ b/DCHdigi/dataFormatExtension/driftChamberHit.yaml @@ -43,7 +43,7 @@ datatypes: - extension::DriftChamberDigi digi // reference to the digitized hit - edm4hep::SimTrackerHit sim // reference to the simulated hit - extension::DriftChamberDigiV2: + edm4hep::DriftChamberDigiV2: Description: "Digitized hit (before tracking) for Drift Chamber v2 (requires data extension)." Author: "A. Tolosa-Delgado, B. Francois, CERN" Members: @@ -59,11 +59,28 @@ datatypes: - uint32_t clusterCount // number of clusters associated to this hit - uint32_t clusterSize // number of electrons per cluster - extension::MCRecoDriftChamberDigiV2Association: + edm4hep::MCRecoDriftChamberDigiV2Association: Description: "Association between a DriftChamberDigi and the corresponding simulated hit" Author: "B. Francois, CERN" Members: - float weight // weight of this association OneToOneRelations: - - extension::DriftChamberDigiV2 digi // reference to the digitized hit + - edm4hep::DriftChamberDigiV2 digi // reference to the digitized hit - edm4hep::SimTrackerHit sim // reference to the simulated hit + +interfaces: + edm4hep::TrackerHit: + Description: "Evolution of tracker hit interface class" + Author: "Thomas Madlener, DESY" + Members: + - uint64_t cellID // ID of the sensor that created this hit + - int32_t type // type of the raw data hit + - int32_t quality // quality bit flag of the hit + - float time [ns] // time of the hit + - float eDep [GeV] // energy deposited on the hit + - float eDepError [GeV] // error measured on eDep + - edm4hep::Vector3d position [mm] // hit position + Types: + - edm4hep::TrackerHit3D + - edm4hep::TrackerHitPlane + - edm4hep::DriftChamberDigiV2 diff --git a/DCHdigi/include/DCHdigi.h b/DCHdigi/include/DCHdigi.h index 1a438db..a9cf72d 100644 --- a/DCHdigi/include/DCHdigi.h +++ b/DCHdigi/include/DCHdigi.h @@ -78,14 +78,14 @@ constexpr double MM_TO_CM = 0.1; struct DCHdigi final : k4FWCore::MultiTransformer< - std::tuple( + std::tuple( const edm4hep::SimTrackerHitCollection&, const edm4hep::EventHeaderCollection&)> { DCHdigi(const std::string& name, ISvcLocator* svcLoc); StatusCode initialize() override; StatusCode finalize() override; - std::tuple operator()( + std::tuple operator()( const edm4hep::SimTrackerHitCollection& , const edm4hep::EventHeaderCollection& ) const override; diff --git a/DCHdigi/src/DCHdigi.cpp b/DCHdigi/src/DCHdigi.cpp index 5e00be4..1880ad4 100644 --- a/DCHdigi/src/DCHdigi.cpp +++ b/DCHdigi/src/DCHdigi.cpp @@ -97,7 +97,7 @@ StatusCode DCHdigi::initialize() { /////////////////////////////////////////////////////////////////////////////////////// /////////////////////// operator() //////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// -std::tuple +std::tuple DCHdigi::operator()(const edm4hep::SimTrackerHitCollection& input_sim_hits, const edm4hep::EventHeaderCollection& headers) const { @@ -107,8 +107,8 @@ DCHdigi::operator()(const edm4hep::SimTrackerHitCollection& input_sim_hits, debug() << "Input Sim Hit collection size: " << input_sim_hits.size() << endmsg; // Create the collections we are going to return - extension::DriftChamberDigiV2Collection output_digi_hits; - extension::MCRecoDriftChamberDigiV2AssociationCollection output_digi_sim_association; + edm4hep::DriftChamberDigiV2Collection output_digi_hits; + edm4hep::MCRecoDriftChamberDigiV2AssociationCollection output_digi_sim_association; //loop over hit collection for (const auto& input_sim_hit : input_sim_hits) @@ -162,7 +162,7 @@ DCHdigi::operator()(const edm4hep::SimTrackerHitCollection& input_sim_hits, auto [clusterCount,clusterSize] = CalculateClusters(input_sim_hit); - extension::MutableDriftChamberDigiV2 oDCHdigihit; + edm4hep::MutableDriftChamberDigiV2 oDCHdigihit; oDCHdigihit.setCellID(input_sim_hit.getCellID()); oDCHdigihit.setType(type); oDCHdigihit.setQuality(quality); @@ -177,7 +177,7 @@ DCHdigi::operator()(const edm4hep::SimTrackerHitCollection& input_sim_hits, output_digi_hits.push_back(oDCHdigihit); - extension::MutableMCRecoDriftChamberDigiV2Association oDCHsimdigi_association; + edm4hep::MutableMCRecoDriftChamberDigiV2Association oDCHsimdigi_association; oDCHsimdigi_association.setDigi( oDCHdigihit ); oDCHsimdigi_association.setSim( input_sim_hit ); output_digi_sim_association.push_back(oDCHsimdigi_association); @@ -185,7 +185,7 @@ DCHdigi::operator()(const edm4hep::SimTrackerHitCollection& input_sim_hits, }// end loop over hit collection ///////////////////////////////////////////////////////////////// - return std::make_tuple(std::move(output_digi_hits),std::move(output_digi_sim_association)); + return std::make_tuple(std::move(output_digi_hits),std::move(output_digi_sim_association)); } /////////////////////////////////////////////////////////////////////////////////////// From a47b0b028bff441077c1af3157aa744a16a13eb9 Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Thu, 29 Aug 2024 11:08:52 +0200 Subject: [PATCH 29/56] implement Thomas suggestion, exit code removed --- .../test/test_DCHdigi/check_DCHdigi_output.py | 51 +++++++++++-------- DCHdigi/test/test_DCHdigi/test_DCHdigi.sh | 5 +- 2 files changed, 30 insertions(+), 26 deletions(-) diff --git a/DCHdigi/test/test_DCHdigi/check_DCHdigi_output.py b/DCHdigi/test/test_DCHdigi/check_DCHdigi_output.py index afc58de..b84d219 100644 --- a/DCHdigi/test/test_DCHdigi/check_DCHdigi_output.py +++ b/DCHdigi/test/test_DCHdigi/check_DCHdigi_output.py @@ -7,28 +7,35 @@ # 2 : problem with calculation of hit-projection position onto the wire import ROOT +import sys -exit_code=0 -# open debug output file generated by DCHdigi alg -f=ROOT.TFile("dch_digi_alg_debug.root") +def main(): + exit_code = 0 + + # Open debug output file generated by DCHdigi alg + f = ROOT.TFile("dch_digi_alg_debug.root") + + # Retrieve the hit-wire distance distribution + hDpw = f.Get("hDpw") + hDpw.Rebin(10) + + # Retrieve the distance at which the distance distribution has its maximum + distance_hit_wire_more_frequent = hDpw.GetXaxis().GetBinCenter(hDpw.GetMaximumBin()) + + # Check if the distance hit wire has the maximum around d=0.66cm + if 0.05 < abs(distance_hit_wire_more_frequent - 0.65): + exit_code += 1 + + # Retrieve the hit-projection onto the wire to the wire distance distribution + hDww = f.Get("hDww") + + # Check the integral, excluding the first bin + hDww_integral = hDww.Integral(2, -1) + if hDww_integral != 0: + exit_code += 2 -# retrieve the hit-wire distance distribution -hDpw=f.Get("hDpw") -hDpw.Rebin(10) -# retrieve the distance at which the distance distribution has its maximum -distance_hit_wire_more_frequent=hDpw.GetXaxis().GetBinCenter( hDpw.GetMaximumBin() ) -# the distance hit wire has the maximum around d=0.66cm -# if it is not the case, that means something weird is going on... -if 0.05 < abs(distance_hit_wire_more_frequent - 0.65) : - exit_code+=1 + return exit_code -# retrieve the hit-projection onto the wire to the wire distance distribution -hDww=f.Get("hDww") -# since the hit-projection onto the wire should be a point on the wire, the distance should be zero -# and all the counts are pushed to the bin number 1 (which is excluded from the integral) -hDww_integral=hDww.Integral(2,-1) -if hDww_integral != 0 : - exit_code+=2 - -# we have to print the exit code, so it can be captured by the bash script -print(exit_code) +if __name__ == "__main__": + code = main() + sys.exit(code) diff --git a/DCHdigi/test/test_DCHdigi/test_DCHdigi.sh b/DCHdigi/test/test_DCHdigi/test_DCHdigi.sh index f218ccd..6163b6e 100644 --- a/DCHdigi/test/test_DCHdigi/test_DCHdigi.sh +++ b/DCHdigi/test/test_DCHdigi/test_DCHdigi.sh @@ -21,7 +21,4 @@ fi k4run runDCHdigi.py # check distribution of distance from hit position to the wire -check_DCHdigi_output=$( (python3 check_DCHdigi_output.py) 2>&1) - -# return value printed out by the previous python script -exit $check_DCHdigi_output +python3 check_DCHdigi_output.py From d6c1c9eb657573c21ab5cadc579007d623eb3e0b Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Fri, 30 Aug 2024 17:56:56 +0200 Subject: [PATCH 30/56] moving back new edm4hep classes to extension namespace --- .../dataFormatExtension/driftChamberHit.yaml | 23 +++---------------- DCHdigi/include/DCHdigi.h | 6 ++--- DCHdigi/src/DCHdigi.cpp | 12 +++++----- 3 files changed, 12 insertions(+), 29 deletions(-) diff --git a/DCHdigi/dataFormatExtension/driftChamberHit.yaml b/DCHdigi/dataFormatExtension/driftChamberHit.yaml index fd42930..228668e 100644 --- a/DCHdigi/dataFormatExtension/driftChamberHit.yaml +++ b/DCHdigi/dataFormatExtension/driftChamberHit.yaml @@ -43,7 +43,7 @@ datatypes: - extension::DriftChamberDigi digi // reference to the digitized hit - edm4hep::SimTrackerHit sim // reference to the simulated hit - edm4hep::DriftChamberDigiV2: + extension::DriftChamberDigiV2: Description: "Digitized hit (before tracking) for Drift Chamber v2 (requires data extension)." Author: "A. Tolosa-Delgado, B. Francois, CERN" Members: @@ -59,28 +59,11 @@ datatypes: - uint32_t clusterCount // number of clusters associated to this hit - uint32_t clusterSize // number of electrons per cluster - edm4hep::MCRecoDriftChamberDigiV2Association: + extension::MCRecoDriftChamberDigiV2Association: Description: "Association between a DriftChamberDigi and the corresponding simulated hit" Author: "B. Francois, CERN" Members: - float weight // weight of this association OneToOneRelations: - - edm4hep::DriftChamberDigiV2 digi // reference to the digitized hit + - extension::DriftChamberDigiV2 digi // reference to the digitized hit - edm4hep::SimTrackerHit sim // reference to the simulated hit - -interfaces: - edm4hep::TrackerHit: - Description: "Evolution of tracker hit interface class" - Author: "Thomas Madlener, DESY" - Members: - - uint64_t cellID // ID of the sensor that created this hit - - int32_t type // type of the raw data hit - - int32_t quality // quality bit flag of the hit - - float time [ns] // time of the hit - - float eDep [GeV] // energy deposited on the hit - - float eDepError [GeV] // error measured on eDep - - edm4hep::Vector3d position [mm] // hit position - Types: - - edm4hep::TrackerHit3D - - edm4hep::TrackerHitPlane - - edm4hep::DriftChamberDigiV2 diff --git a/DCHdigi/include/DCHdigi.h b/DCHdigi/include/DCHdigi.h index a9cf72d..08659a4 100644 --- a/DCHdigi/include/DCHdigi.h +++ b/DCHdigi/include/DCHdigi.h @@ -12,7 +12,7 @@ * Processor produces collection of Digitized hits of Drift Chamber v2
* @param DCH_simhits The name of input collection, type edm4hep::SimTrackerHitCollection
* (default name empty)
- * @param DCH_DigiCollection The name of out collection, type edm4hep::DriftChamberDigiV2Collection
+ * @param DCH_DigiCollection The name of out collection, type extension::DriftChamberDigiV2Collection
* (default name DCH_DigiCollection)
* @param DCH_name DCH subdetector name
* (default value DCH_v2)
@@ -78,14 +78,14 @@ constexpr double MM_TO_CM = 0.1; struct DCHdigi final : k4FWCore::MultiTransformer< - std::tuple( + std::tuple( const edm4hep::SimTrackerHitCollection&, const edm4hep::EventHeaderCollection&)> { DCHdigi(const std::string& name, ISvcLocator* svcLoc); StatusCode initialize() override; StatusCode finalize() override; - std::tuple operator()( + std::tuple operator()( const edm4hep::SimTrackerHitCollection& , const edm4hep::EventHeaderCollection& ) const override; diff --git a/DCHdigi/src/DCHdigi.cpp b/DCHdigi/src/DCHdigi.cpp index 1880ad4..5e00be4 100644 --- a/DCHdigi/src/DCHdigi.cpp +++ b/DCHdigi/src/DCHdigi.cpp @@ -97,7 +97,7 @@ StatusCode DCHdigi::initialize() { /////////////////////////////////////////////////////////////////////////////////////// /////////////////////// operator() //////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// -std::tuple +std::tuple DCHdigi::operator()(const edm4hep::SimTrackerHitCollection& input_sim_hits, const edm4hep::EventHeaderCollection& headers) const { @@ -107,8 +107,8 @@ DCHdigi::operator()(const edm4hep::SimTrackerHitCollection& input_sim_hits, debug() << "Input Sim Hit collection size: " << input_sim_hits.size() << endmsg; // Create the collections we are going to return - edm4hep::DriftChamberDigiV2Collection output_digi_hits; - edm4hep::MCRecoDriftChamberDigiV2AssociationCollection output_digi_sim_association; + extension::DriftChamberDigiV2Collection output_digi_hits; + extension::MCRecoDriftChamberDigiV2AssociationCollection output_digi_sim_association; //loop over hit collection for (const auto& input_sim_hit : input_sim_hits) @@ -162,7 +162,7 @@ DCHdigi::operator()(const edm4hep::SimTrackerHitCollection& input_sim_hits, auto [clusterCount,clusterSize] = CalculateClusters(input_sim_hit); - edm4hep::MutableDriftChamberDigiV2 oDCHdigihit; + extension::MutableDriftChamberDigiV2 oDCHdigihit; oDCHdigihit.setCellID(input_sim_hit.getCellID()); oDCHdigihit.setType(type); oDCHdigihit.setQuality(quality); @@ -177,7 +177,7 @@ DCHdigi::operator()(const edm4hep::SimTrackerHitCollection& input_sim_hits, output_digi_hits.push_back(oDCHdigihit); - edm4hep::MutableMCRecoDriftChamberDigiV2Association oDCHsimdigi_association; + extension::MutableMCRecoDriftChamberDigiV2Association oDCHsimdigi_association; oDCHsimdigi_association.setDigi( oDCHdigihit ); oDCHsimdigi_association.setSim( input_sim_hit ); output_digi_sim_association.push_back(oDCHsimdigi_association); @@ -185,7 +185,7 @@ DCHdigi::operator()(const edm4hep::SimTrackerHitCollection& input_sim_hits, }// end loop over hit collection ///////////////////////////////////////////////////////////////// - return std::make_tuple(std::move(output_digi_hits),std::move(output_digi_sim_association)); + return std::make_tuple(std::move(output_digi_hits),std::move(output_digi_sim_association)); } /////////////////////////////////////////////////////////////////////////////////////// From 034afab7cc9f7a1fabd31d3cde803829e50460ee Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Mon, 2 Sep 2024 16:49:07 +0200 Subject: [PATCH 31/56] add interface back again... --- .../dataFormatExtension/driftChamberHit.yaml | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/DCHdigi/dataFormatExtension/driftChamberHit.yaml b/DCHdigi/dataFormatExtension/driftChamberHit.yaml index 228668e..e2a1e9b 100644 --- a/DCHdigi/dataFormatExtension/driftChamberHit.yaml +++ b/DCHdigi/dataFormatExtension/driftChamberHit.yaml @@ -67,3 +67,76 @@ datatypes: OneToOneRelations: - extension::DriftChamberDigiV2 digi // reference to the digitized hit - edm4hep::SimTrackerHit sim // reference to the simulated hit + +# the following is just because interface looks for e.g. extension/TrackerHit3DCollection.h + extension::TrackerHit3D: + Description: "Tracker hit" + Author: "EDM4hep authors" + Members: + - uint64_t cellID // ID of the sensor that created this hit + - int32_t type // type of raw data hit + - int32_t quality // quality bit flag of the hit + - float time [ns] // time of the hit + - float eDep [GeV] // energy deposited on the hit + - float eDepError [GeV] // error measured on EDep + - edm4hep::Vector3d position [mm] // hit position + - edm4hep::CovMatrix3f covMatrix // covariance matrix of the position (x,y,z) + ExtraCode: + includes: "#include " + declaration: " + /// Get the position covariance matrix value for the two passed dimensions\n + float getCovMatrix(edm4hep::Cartesian dimI, edm4hep::Cartesian dimJ) const { return getCovMatrix().getValue(dimI, dimJ); }\n + " + MutableExtraCode: + includes: "#include " + declaration: " + /// Set the position covariance matrix value for the two passed dimensions\n + void setCovMatrix(float value, edm4hep::Cartesian dimI, edm4hep::Cartesian dimJ) { getCovMatrix().setValue(value, dimI, dimJ); }\n + " + extension::TrackerHitPlane: + Description: "Tracker hit plane" + Author: "EDM4hep authors" + Members: + - uint64_t cellID // ID of the sensor that created this hit + - int32_t type // type of raw data hit + - int32_t quality // quality bit flag of the hit + - float time [ns] // time of the hit + - float eDep [GeV] // energy deposited on the hit + - float eDepError [GeV] // error measured on EDep + - edm4hep::Vector2f u // measurement direction vector, u lies in the x-y plane + - edm4hep::Vector2f v // measurement direction vector, v is along z + - float du // measurement error along the direction + - float dv // measurement error along the direction + - edm4hep::Vector3d position [mm] // hit position + - edm4hep::CovMatrix3f covMatrix // covariance of the position (x,y,z) + ExtraCode: + includes: "#include " + declaration: " + /// Get the position covariance matrix value for the two passed dimensions\n + float getCovMatrix(edm4hep::Cartesian dimI, edm4hep::Cartesian dimJ) const { return getCovMatrix().getValue(dimI, dimJ); }\n + " + MutableExtraCode: + includes: "#include " + declaration: " + /// Set the position covariance matrix value for the two passed dimensions\n + void setCovMatrix(float value, edm4hep::Cartesian dimI, edm4hep::Cartesian dimJ) { getCovMatrix().setValue(value, dimI, dimJ); }\n + " + +# end of "the following is just because interface looks for e.g. extension/TrackerHit3DCollection.h" + +interfaces: + extension::TrackerHit: + Description: "Tracker hit interface class" + Author: "Thomas Madlener, DESY" + Members: + - uint64_t cellID // ID of the sensor that created this hit + - int32_t type // type of the raw data hit + - int32_t quality // quality bit flag of the hit + - float time [ns] // time of the hit + - float eDep [GeV] // energy deposited on the hit + - float eDepError [GeV] // error measured on eDep + - edm4hep::Vector3d position [mm] // hit position + Types: + - extension::TrackerHitPlane + - extension::TrackerHit3D + - extension::DriftChamberDigiV2 From fc131e522b6cc7e50948f66cfde8e31b3999cfbc Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Sat, 21 Sep 2024 17:48:55 +0200 Subject: [PATCH 32/56] add extension::Track --- .../dataFormatExtension/driftChamberHit.yaml | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/DCHdigi/dataFormatExtension/driftChamberHit.yaml b/DCHdigi/dataFormatExtension/driftChamberHit.yaml index e2a1e9b..193a2fd 100644 --- a/DCHdigi/dataFormatExtension/driftChamberHit.yaml +++ b/DCHdigi/dataFormatExtension/driftChamberHit.yaml @@ -67,7 +67,25 @@ datatypes: OneToOneRelations: - extension::DriftChamberDigiV2 digi // reference to the digitized hit - edm4hep::SimTrackerHit sim // reference to the simulated hit - + + extension::Track: + Description: "Reconstructed track" + Author: "EDM4hep authors" + Members: + - int32_t type // flagword that defines the type of track.Bits 16-31 are used internally + - float chi2 // Chi^2 of the track fit + - int32_t ndf // number of degrees of freedom of the track fit + - float dEdx // dEdx of the track + - float dEdxError // error of dEdx + - float radiusOfInnermostHit // radius of the innermost hit that has been used in the track fit + VectorMembers: + - int32_t subdetectorHitNumbers // number of hits in particular subdetectors + - edm4hep::TrackState trackStates // track states + - edm4hep::Quantity dxQuantities // different measurements of dx quantities + OneToManyRelations: + - extension::TrackerHit trackerHits // hits that have been used to create this track + - extension::Track tracks // tracks (segments) that have been combined to create this track + # the following is just because interface looks for e.g. extension/TrackerHit3DCollection.h extension::TrackerHit3D: Description: "Tracker hit" From 70cd63a2f915c12a2721a1f8132320a81bee7aa1 Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Sat, 21 Sep 2024 17:59:07 +0200 Subject: [PATCH 33/56] rename of cluster variables --- DCHdigi/dataFormatExtension/driftChamberHit.yaml | 4 ++-- DCHdigi/src/DCHdigi.cpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/DCHdigi/dataFormatExtension/driftChamberHit.yaml b/DCHdigi/dataFormatExtension/driftChamberHit.yaml index 193a2fd..8644114 100644 --- a/DCHdigi/dataFormatExtension/driftChamberHit.yaml +++ b/DCHdigi/dataFormatExtension/driftChamberHit.yaml @@ -56,8 +56,8 @@ datatypes: - edm4hep::Vector3d position // point on the sensitive wire (SW) which is closest to the simhit [mm] - edm4hep::Vector3d directionSW // direction of SW - float distanceToWire // distance hit-wire [mm] - - uint32_t clusterCount // number of clusters associated to this hit - - uint32_t clusterSize // number of electrons per cluster + - uint32_t nCluster // number of clusters associated to this hit + - uint32_t nElectronPerCluster // number of electrons per cluster extension::MCRecoDriftChamberDigiV2Association: Description: "Association between a DriftChamberDigi and the corresponding simulated hit" diff --git a/DCHdigi/src/DCHdigi.cpp b/DCHdigi/src/DCHdigi.cpp index 5e00be4..a83e611 100644 --- a/DCHdigi/src/DCHdigi.cpp +++ b/DCHdigi/src/DCHdigi.cpp @@ -160,7 +160,7 @@ DCHdigi::operator()(const edm4hep::SimTrackerHitCollection& input_sim_hits, auto directionSW = Convert_TVector3_to_EDM4hepVector(wire_direction_ez , 1./MM_TO_CM ); float distanceToWire = distanceToWire_smeared/MM_TO_CM; - auto [clusterCount,clusterSize] = CalculateClusters(input_sim_hit); + auto [nCluster,nElectronPerCluster] = CalculateClusters(input_sim_hit); extension::MutableDriftChamberDigiV2 oDCHdigihit; oDCHdigihit.setCellID(input_sim_hit.getCellID()); @@ -172,8 +172,8 @@ DCHdigi::operator()(const edm4hep::SimTrackerHitCollection& input_sim_hits, oDCHdigihit.setPosition(positionSW); oDCHdigihit.setDirectionSW(directionSW); oDCHdigihit.setDistanceToWire(distanceToWire); - oDCHdigihit.setClusterCount(clusterCount); - oDCHdigihit.setClusterSize(clusterSize); + oDCHdigihit.setNCluster(nCluster); + oDCHdigihit.setNElectronPerCluster(nElectronPerCluster); output_digi_hits.push_back(oDCHdigihit); From 7ab557010ff4a411d61a8f29ff20163af70a60e5 Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Sat, 21 Sep 2024 18:19:59 +0200 Subject: [PATCH 34/56] indentantion is compliant with local .clang-format file --- DCHdigi/include/AlgData.h | 1076 ++++++++++++++++++------------------- DCHdigi/include/DCHdigi.h | 88 ++- DCHdigi/src/DCHdigi.cpp | 664 ----------------------- 3 files changed, 552 insertions(+), 1276 deletions(-) diff --git a/DCHdigi/include/AlgData.h b/DCHdigi/include/AlgData.h index 5289459..d43f2b3 100644 --- a/DCHdigi/include/AlgData.h +++ b/DCHdigi/include/AlgData.h @@ -3,591 +3,535 @@ #include -#include "TTree.h" +#include +#include +#include +#include "Math/InterpolationTypes.h" +#include "Math/Interpolator.h" +#include "TCanvas.h" #include "TChain.h" #include "TF1.h" -#include "TCanvas.h" -#include "TGraph.h" #include "TFile.h" -#include -#include "Math/Interpolator.h" -#include "Math/InterpolationTypes.h" -#include -#include - - +#include "TGraph.h" +#include "TTree.h" -class AlgData{ +class AlgData { public: - inline AlgData(); - inline ~AlgData(); + inline AlgData(); + inline ~AlgData(); public: - inline void read_file(TString dataAlg); - inline TF1* read_graph(TString dataAlg, TString cvName, TString fitName); - - - inline TF1* get_fit(); - inline TFormula* get_formula(); - inline double get_Fitvalue(double betagamma) const; - inline ROOT::Math::Interpolator* Interpvalue(std::vector bg, std::vector Ydata,int Intertype); - inline void Load_file(TString dataAlg); - inline void Load_interp(); - inline double get_MPVExtra (double betagamma) const; - inline double get_SgmExtra (double betagamma) const; - inline double get_MeanExtra1 (double betagamma) const; - inline double get_SgmExtra1 (double betagamma) const; - inline double get_SlopeExtra1 (double betagamma)const; - inline double get_FracExtra1(double betagamma) const; - inline double get_FfracExtra(double betagamma) ; - inline double get_maxEx0(double betagamma); - inline double get_maxExSlp(); - inline double get_ExSgmlep(); - inline double get_ExSgmhad(); - inline double get_Ffrac(double betagamma); - inline double get_Fmpv1(double betagamma); - inline double get_Fsgm1(double betagamma); - inline double get_Fmpv2(double betagamma); - inline double get_Fsgm2(double betagamma); - inline double get_ClSzCorrInt(double betagamma); - inline double get_ClSzCorrSlp(double betagamma); - inline std::vector get_ClSzCorrpmean(double betagamma); - inline std::vector get_ClSzCorrpsgm(double betagamma); - - inline std::vector get_ClSzCorrdgmean(double betagamma); - inline std::vector get_ClSzCorrdgsgm(double betagamma); - - inline std::vector get_ClSzCorrdglfrac(double betagamma); - inline std::vector get_ClSzCorrdglmpvl(double betagamma); - inline std::vector get_ClSzCorrdglsgml(double betagamma); - inline std::vector get_ClSzCorrdglmeang(double betagamma); - inline std::vector get_ClSzCorrdglsgmg(double betagamma); - + inline void read_file(TString dataAlg); + inline TF1* read_graph(TString dataAlg, TString cvName, TString fitName); + + inline TF1* get_fit(); + inline TFormula* get_formula(); + inline double get_Fitvalue(double betagamma) const; + inline ROOT::Math::Interpolator* Interpvalue(std::vector bg, std::vector Ydata, int Intertype); + inline void Load_file(TString dataAlg); + inline void Load_interp(); + inline double get_MPVExtra(double betagamma) const; + inline double get_SgmExtra(double betagamma) const; + inline double get_MeanExtra1(double betagamma) const; + inline double get_SgmExtra1(double betagamma) const; + inline double get_SlopeExtra1(double betagamma) const; + inline double get_FracExtra1(double betagamma) const; + inline double get_FfracExtra(double betagamma); + inline double get_maxEx0(double betagamma); + inline double get_maxExSlp(); + inline double get_ExSgmlep(); + inline double get_ExSgmhad(); + inline double get_Ffrac(double betagamma); + inline double get_Fmpv1(double betagamma); + inline double get_Fsgm1(double betagamma); + inline double get_Fmpv2(double betagamma); + inline double get_Fsgm2(double betagamma); + inline double get_ClSzCorrInt(double betagamma); + inline double get_ClSzCorrSlp(double betagamma); + inline std::vector get_ClSzCorrpmean(double betagamma); + inline std::vector get_ClSzCorrpsgm(double betagamma); + + inline std::vector get_ClSzCorrdgmean(double betagamma); + inline std::vector get_ClSzCorrdgsgm(double betagamma); + + inline std::vector get_ClSzCorrdglfrac(double betagamma); + inline std::vector get_ClSzCorrdglmpvl(double betagamma); + inline std::vector get_ClSzCorrdglsgml(double betagamma); + inline std::vector get_ClSzCorrdglmeang(double betagamma); + inline std::vector get_ClSzCorrdglsgmg(double betagamma); private: - TString DataAlg; - TChain *data1; - TChain *datalep; - TChain *datahad; - TFile *file; - - double bgT,bgTlep,bgThad,tmpmaxEx0Tot,tmpErrmaxEx0Tot,tmpmaxExSlpTot,tmpErrmaxExSlpTot,tmpExSgmTotlep,tmpExSgmTothad; - double tmptFfracTot,tmptFerrfracTot,tmptFmpv1Tot,tmptFerrmpv1Tot,tmptFsgm1Tot,tmptFerrsgm1Tot,tmptFmpv2Tot,tmptFerrmpv2Tot,tmptFsgm2Tot,tmptFerrsgm2Tot; - double tmpCorrIntTot,tmpErrCorrIntTot,tmpCorrSlpTot,tmpErrCorrSlpTot; - - std::vector *tmpCorrmeanSliceTot=nullptr; - std::vector *tmpErrCorrmeanSliceTot=nullptr; - std::vector *tmpCorrsgmSliceTot=nullptr; - std::vector *tmpErrCorrsgmSliceTot=nullptr; - - std::vector *tmpCorrdglfracSliceTot=nullptr; - std::vector *tmpErrCorrdglfracSliceTot=nullptr; - std::vector *tmpCorrdglmeangSliceTot=nullptr; - std::vector *tmpErrCorrdglmeangSliceTot=nullptr; - std::vector *tmpCorrdglsgmgSliceTot=nullptr; - std::vector *tmpErrCorrdglsgmgSliceTot=nullptr; - std::vector *tmpCorrdglmpvSliceTot=nullptr; - std::vector *tmpErrCorrdglmpvSliceTot=nullptr; - std::vector *tmpCorrdglsgmlSliceTot=nullptr; - std::vector *tmpErrCorrdglsgmlSliceTot=nullptr; - - std::vector *tmpCorrdgmeanSliceTot=nullptr; - std::vector *tmpErrCorrdgmeanSliceTot=nullptr; - std::vector *tmpCorrdgsgmSliceTot=nullptr; - std::vector *tmpErrCorrdgsgmSliceTot=nullptr; - - //____________________________________________________// - std::vector bgv,bglep,bghad; - std::vector maxEx0Tot,ErrmaxEx0Tot,maxExSlpTot,ErrmaxExSlpTot,ExSgmTotlep,ExSgmTothad; - std::vector tFfracTot, tFerrfracTot, tFmpv1Tot, tFerrmpv1Tot, tFsgm1Tot, tFerrsgm1Tot, tFmpv2Tot, tFerrmpv2Tot, tFsgm2Tot, tFerrsgm2Tot; - std::vector CorrmeanSliceTot[20],ErrCorrmeanSliceTot[20],CorrsgmSliceTot[20],ErrCorrsgmSliceTot[20]; - std::vector CorrIntTot,ErrCorrIntTot,CorrSlpTot,ErrCorrSlpTot; - std::vector CorrdglfracSliceTot[20],ErrCorrdglfracSliceTot[20],CorrdglmeangSliceTot[20],ErrCorrdglmeangSliceTot[20],CorrdglsgmgSliceTot[20],ErrCorrdglsgmgSliceTot[20],CorrdglmpvSliceTot[20],ErrCorrdglmpvSliceTot[20],CorrdglsgmlSliceTot[20],ErrCorrdglsgmlSliceTot[20]; - std::vector CorrdgmeanSliceTot[20],ErrCorrdgmeanSliceTot[20],CorrdgsgmSliceTot[20],ErrCorrdgsgmSliceTot[20]; - - //__________________________________________// - TF1 *Ft; - TF1 *FitMPVExtra; - TF1 *FitSgmExtra; - TF1 *FitMeanExtra1; - TF1 *FitSgmExtra1; - TF1 *FitSlopeExtra1; - TF1 *FitFracExtra1; - - TFormula *FtFormula; - - std::vector Corrmean; - std::vector Corrsgm; - - std::vector Corrdgmean; - std::vector Corrdgsgm; - - std::vector Corrdglfrac; - std::vector Corrdglmeang; - std::vector Corrdglsgmg; - std::vector Corrdglmpv; - std::vector Corrdglsgml; - - std::vector ClSzCorrpmean; - std::vector ClSzCorrpsgm; - std::vector ClSzCorrdgmean; - std::vector ClSzCorrdgsgm; - std::vector ClSzCorrdglfrac; - std::vector ClSzCorrdglmpvl; - std::vector ClSzCorrdglsgml; - std::vector ClSzCorrdglmeang; - std::vector ClSzCorrdglsgmg; - - double maxExSlp; - double ExSgmlep; - double ExSgmhad; - inline void Calc_maxExSlp(); - inline void Calc_ExSgmlep(); - inline void Calc_ExSgmhad(); - - - - //___________________________________________// - - std::map itpm; - ROOT::Math::Interpolator* itp1; - + TString DataAlg; + TChain* data1; + TChain* datalep; + TChain* datahad; + TFile* file; + + double bgT, bgTlep, bgThad, tmpmaxEx0Tot, tmpErrmaxEx0Tot, tmpmaxExSlpTot, tmpErrmaxExSlpTot, tmpExSgmTotlep, + tmpExSgmTothad; + double tmptFfracTot, tmptFerrfracTot, tmptFmpv1Tot, tmptFerrmpv1Tot, tmptFsgm1Tot, tmptFerrsgm1Tot, tmptFmpv2Tot, + tmptFerrmpv2Tot, tmptFsgm2Tot, tmptFerrsgm2Tot; + double tmpCorrIntTot, tmpErrCorrIntTot, tmpCorrSlpTot, tmpErrCorrSlpTot; + + std::vector* tmpCorrmeanSliceTot = nullptr; + std::vector* tmpErrCorrmeanSliceTot = nullptr; + std::vector* tmpCorrsgmSliceTot = nullptr; + std::vector* tmpErrCorrsgmSliceTot = nullptr; + + std::vector* tmpCorrdglfracSliceTot = nullptr; + std::vector* tmpErrCorrdglfracSliceTot = nullptr; + std::vector* tmpCorrdglmeangSliceTot = nullptr; + std::vector* tmpErrCorrdglmeangSliceTot = nullptr; + std::vector* tmpCorrdglsgmgSliceTot = nullptr; + std::vector* tmpErrCorrdglsgmgSliceTot = nullptr; + std::vector* tmpCorrdglmpvSliceTot = nullptr; + std::vector* tmpErrCorrdglmpvSliceTot = nullptr; + std::vector* tmpCorrdglsgmlSliceTot = nullptr; + std::vector* tmpErrCorrdglsgmlSliceTot = nullptr; + + std::vector* tmpCorrdgmeanSliceTot = nullptr; + std::vector* tmpErrCorrdgmeanSliceTot = nullptr; + std::vector* tmpCorrdgsgmSliceTot = nullptr; + std::vector* tmpErrCorrdgsgmSliceTot = nullptr; + + //____________________________________________________// + std::vector bgv, bglep, bghad; + std::vector maxEx0Tot, ErrmaxEx0Tot, maxExSlpTot, ErrmaxExSlpTot, ExSgmTotlep, ExSgmTothad; + std::vector tFfracTot, tFerrfracTot, tFmpv1Tot, tFerrmpv1Tot, tFsgm1Tot, tFerrsgm1Tot, tFmpv2Tot, + tFerrmpv2Tot, tFsgm2Tot, tFerrsgm2Tot; + std::vector CorrmeanSliceTot[20], ErrCorrmeanSliceTot[20], CorrsgmSliceTot[20], ErrCorrsgmSliceTot[20]; + std::vector CorrIntTot, ErrCorrIntTot, CorrSlpTot, ErrCorrSlpTot; + std::vector CorrdglfracSliceTot[20], ErrCorrdglfracSliceTot[20], CorrdglmeangSliceTot[20], + ErrCorrdglmeangSliceTot[20], CorrdglsgmgSliceTot[20], ErrCorrdglsgmgSliceTot[20], CorrdglmpvSliceTot[20], + ErrCorrdglmpvSliceTot[20], CorrdglsgmlSliceTot[20], ErrCorrdglsgmlSliceTot[20]; + std::vector CorrdgmeanSliceTot[20], ErrCorrdgmeanSliceTot[20], CorrdgsgmSliceTot[20], + ErrCorrdgsgmSliceTot[20]; + + //__________________________________________// + TF1* Ft; + TF1* FitMPVExtra; + TF1* FitSgmExtra; + TF1* FitMeanExtra1; + TF1* FitSgmExtra1; + TF1* FitSlopeExtra1; + TF1* FitFracExtra1; + + TFormula* FtFormula; + + std::vector Corrmean; + std::vector Corrsgm; + + std::vector Corrdgmean; + std::vector Corrdgsgm; + + std::vector Corrdglfrac; + std::vector Corrdglmeang; + std::vector Corrdglsgmg; + std::vector Corrdglmpv; + std::vector Corrdglsgml; + + std::vector ClSzCorrpmean; + std::vector ClSzCorrpsgm; + std::vector ClSzCorrdgmean; + std::vector ClSzCorrdgsgm; + std::vector ClSzCorrdglfrac; + std::vector ClSzCorrdglmpvl; + std::vector ClSzCorrdglsgml; + std::vector ClSzCorrdglmeang; + std::vector ClSzCorrdglsgmg; + + double maxExSlp; + double ExSgmlep; + double ExSgmhad; + inline void Calc_maxExSlp(); + inline void Calc_ExSgmlep(); + inline void Calc_ExSgmhad(); + + //___________________________________________// + + std::map itpm; + ROOT::Math::Interpolator* itp1; }; - //_______________________________________________// +//_______________________________________________// + +AlgData::AlgData() { + DataAlg = ""; + data1 = nullptr; + datalep = nullptr; + datahad = nullptr; + file = nullptr; + + tmpCorrmeanSliceTot = nullptr; + tmpErrCorrmeanSliceTot = nullptr; + tmpCorrsgmSliceTot = nullptr; + tmpErrCorrsgmSliceTot = nullptr; + + tmpCorrdglfracSliceTot = nullptr; + tmpErrCorrdglfracSliceTot = nullptr; + tmpCorrdglmeangSliceTot = nullptr; + tmpErrCorrdglmeangSliceTot = nullptr; + tmpCorrdglsgmgSliceTot = nullptr; + tmpErrCorrdglsgmgSliceTot = nullptr; + tmpCorrdglmpvSliceTot = nullptr; + tmpErrCorrdglmpvSliceTot = nullptr; + tmpCorrdglsgmlSliceTot = nullptr; + tmpErrCorrdglsgmlSliceTot = nullptr; + + tmpCorrdgmeanSliceTot = nullptr; + tmpErrCorrdgmeanSliceTot = nullptr; + tmpCorrdgsgmSliceTot = nullptr; + tmpErrCorrdgsgmSliceTot = nullptr; + + Ft = nullptr; + FtFormula = nullptr; + FitMPVExtra = nullptr; + FitSgmExtra = nullptr; + FitMeanExtra1 = nullptr; + FitSgmExtra1 = nullptr; + FitSlopeExtra1 = nullptr; + FitFracExtra1 = nullptr; +} + +AlgData::~AlgData() { + if (file->IsOpen()) + file->Close(); +} + +void AlgData::read_file(TString dataAlg) { + DataAlg = dataAlg; + + std::cout << " ---reading of---" << DataAlg << std::endl; + + data1 = new TChain("DataAlg"); + datalep = new TChain("DataAlglep"); + datahad = new TChain("DataAlghad"); + + if (dataAlg.Contains(".root")) { + data1->Add(dataAlg.Data()); + datalep->Add(dataAlg.Data()); + datahad->Add(dataAlg.Data()); + } + + data1->SetBranchAddress("bgT", &bgT); + data1->SetBranchAddress("tmpmaxEx0Tot", &tmpmaxEx0Tot); + data1->SetBranchAddress("tmpErrmaxEx0Tot", &tmpErrmaxEx0Tot); + data1->SetBranchAddress("tmpmaxExSlpTot", &tmpmaxExSlpTot); + data1->SetBranchAddress("tmpErrmaxExSlpTot", &tmpErrmaxExSlpTot); + data1->SetBranchAddress("tmptFfracTot", &tmptFfracTot); + data1->SetBranchAddress("tFerrfracTot", &tmptFerrfracTot); + data1->SetBranchAddress("tmptFerrfracTot", &tmptFmpv1Tot); + data1->SetBranchAddress("tmptFerrmpv1Tot", &tmptFerrmpv1Tot); + data1->SetBranchAddress("tmptFerrmpv1Tot", &tmptFerrmpv1Tot); + data1->SetBranchAddress("tmptFsgm1Tot", &tmptFsgm1Tot); + data1->SetBranchAddress("tmptFerrsgm1Tot", &tmptFerrsgm1Tot); + data1->SetBranchAddress("tmptFmpv2Tot", &tmptFmpv2Tot); + data1->SetBranchAddress("tmptFerrmpv2Tot", &tmptFerrmpv2Tot); + data1->SetBranchAddress("tmptFsgm2Tot", &tmptFsgm2Tot); + data1->SetBranchAddress("tmptFerrsgm2Tot", &tmptFerrsgm2Tot); + + data1->SetBranchAddress("tmpCorrIntTot", &tmpCorrIntTot); + data1->SetBranchAddress("tmpErrCorrIntTot", &tmpErrCorrIntTot); + data1->SetBranchAddress("tmpCorrSlpTot", &tmpCorrSlpTot); + data1->SetBranchAddress("tmpErrCorrSlpTot", &tmpErrCorrSlpTot); + + data1->SetBranchAddress("tmpCorrmeanSliceTot", &tmpCorrmeanSliceTot); + data1->SetBranchAddress("tmpErrCorrmeanSliceTot", &tmpErrCorrmeanSliceTot); + data1->SetBranchAddress("tmpCorrsgmSliceTot", &tmpCorrsgmSliceTot); + data1->SetBranchAddress("tmpErrCorrsgmSliceTot", &tmpErrCorrsgmSliceTot); + + data1->SetBranchAddress("tmpCorrdgmeanSliceTot", &tmpCorrdgmeanSliceTot); + data1->SetBranchAddress("tmpErrCorrdgmeanSliceTot", &tmpErrCorrdgmeanSliceTot); + data1->SetBranchAddress("tmpCorrdgsgmSliceTot", &tmpCorrdgsgmSliceTot); + data1->SetBranchAddress("tmpErrCorrdgsgmSliceTot", &tmpErrCorrdgsgmSliceTot); + + data1->SetBranchAddress("tmpCorrdglfracSliceTot", &tmpCorrdglfracSliceTot); + data1->SetBranchAddress("tmpErrCorrdglfracSliceTot", &tmpErrCorrdglfracSliceTot); + data1->SetBranchAddress("tmpCorrdglmeangSliceTot", &tmpCorrdglmeangSliceTot); + data1->SetBranchAddress("tmpErrCorrdglmeangSliceTot", &tmpErrCorrdglmeangSliceTot); + data1->SetBranchAddress("tmpCorrdglsgmgSliceTot", &tmpCorrdglsgmgSliceTot); + data1->SetBranchAddress("tmpErrCorrdglsgmgSliceTot", &tmpErrCorrdglsgmgSliceTot); + data1->SetBranchAddress("tmpCorrdglmpvSliceTot", &tmpCorrdglmpvSliceTot); + data1->SetBranchAddress("tmpErrCorrdglmpvSliceTot", &tmpErrCorrdglmpvSliceTot); + data1->SetBranchAddress("tmpCorrdglsgmlSliceTot", &tmpCorrdglsgmlSliceTot); + data1->SetBranchAddress("tmpErrCorrdglsgmlSliceTot", &tmpErrCorrdglsgmlSliceTot); + + datalep->SetBranchAddress("bgTlep", &bgTlep); + datalep->SetBranchAddress("tmpExSgmTotlep", &tmpExSgmTotlep); + + datahad->SetBranchAddress("bgThad", &bgThad); + datahad->SetBranchAddress("tmpExSgmTothad", &tmpExSgmTothad); + + for (int i = 0; i < data1->GetEntries(); i++) { + data1->GetEntry(i); + bgv.push_back(bgT); + // std::cout<size(); ++j) { + CorrmeanSliceTot[j].push_back(tmpCorrmeanSliceTot->at(j)); + ErrCorrmeanSliceTot[j].push_back(tmpErrCorrmeanSliceTot->at(j)); + CorrsgmSliceTot[j].push_back(tmpCorrsgmSliceTot->at(j)); + ErrCorrsgmSliceTot[j].push_back(tmpErrCorrsgmSliceTot->at(j)); + } + + for (unsigned int n = 0; n < tmpCorrdgmeanSliceTot->size(); ++n) { + CorrdgmeanSliceTot[n].push_back(tmpCorrdgmeanSliceTot->at(n)); + ErrCorrdgmeanSliceTot[n].push_back(tmpErrCorrdgmeanSliceTot->at(n)); + CorrdgsgmSliceTot[n].push_back(tmpCorrdgsgmSliceTot->at(n)); + ErrCorrdgsgmSliceTot[n].push_back(tmpErrCorrdgsgmSliceTot->at(n)); + } + + for (unsigned int k = 0; k < tmpCorrdglfracSliceTot->size(); ++k) { + CorrdglfracSliceTot[k].push_back(tmpCorrdglfracSliceTot->at(k)); + ErrCorrdglfracSliceTot[k].push_back(tmpErrCorrdglfracSliceTot->at(k)); + CorrdglmeangSliceTot[k].push_back(tmpCorrdglmeangSliceTot->at(k)); + ErrCorrdglmeangSliceTot[k].push_back(tmpErrCorrdglmeangSliceTot->at(k)); + CorrdglsgmgSliceTot[k].push_back(tmpCorrdglsgmgSliceTot->at(k)); + ErrCorrdglsgmgSliceTot[k].push_back(tmpErrCorrdglsgmgSliceTot->at(k)); + CorrdglmpvSliceTot[k].push_back(tmpCorrdglmpvSliceTot->at(k)); + ErrCorrdglmpvSliceTot[k].push_back(tmpErrCorrdglmpvSliceTot->at(k)); + CorrdglsgmlSliceTot[k].push_back(tmpCorrdglsgmlSliceTot->at(k)); + ErrCorrdglsgmlSliceTot[k].push_back(tmpErrCorrdglsgmlSliceTot->at(k)); + // std::cout<at(k)<GetEntries(); i++) { + datalep->GetEntry(i); + bglep.push_back(bgTlep); + ExSgmTotlep.push_back(tmpExSgmTotlep); + // std::cout<< " bgTlep "<GetEntries(); i++) { + datahad->GetEntry(i); + bghad.push_back(bgThad); + ExSgmTothad.push_back(tmpExSgmTothad); + } +} + +TF1* AlgData::read_graph(TString dataAlg, TString cvName, TString fitName) { + DataAlg = dataAlg; + file = TFile::Open(dataAlg.Data(), "read"); + TCanvas* cv = (TCanvas*)file->Get(cvName.Data()); + TGraph* gr = (TGraph*)cv->GetListOfPrimitives()->FindObject("Graph"); + TF1* ft = (TF1*)gr->GetListOfFunctions()->FindObject(fitName.Data()); + TFormula* ftFormula = (TFormula*)ft->GetFormula(); + FtFormula = ftFormula; + return ft; +} + +void AlgData::Load_file(TString dataAlg) { + read_file(dataAlg.Data()); + FitMPVExtra = read_graph(dataAlg.Data(), "cMPVExtrabgTot", "fit_MPV"); + FitSgmExtra = read_graph(dataAlg.Data(), "cSgmExtrabgTot", "fit_sgmEx"); + FitMeanExtra1 = read_graph(dataAlg.Data(), "cMeanExtra1bgTot", "expeff"); + FitSgmExtra1 = read_graph(dataAlg.Data(), "cSgmExtra1bgTot", "expeffNeg"); + FitSlopeExtra1 = read_graph(dataAlg.Data(), "cSlopeExtra1bgTot", "fit_slp"); + FitFracExtra1 = read_graph(dataAlg.Data(), "cfracbgTot", "fit_frEx"); + Calc_ExSgmhad(); + Calc_ExSgmlep(); + Calc_maxExSlp(); +} + +TF1* AlgData::get_fit() { return Ft; } + +TFormula* AlgData::get_formula() { return FtFormula; } + +double AlgData::get_MPVExtra(double betagamma) const { return FitMPVExtra->Eval(betagamma); } + +double AlgData::get_SgmExtra(double betagamma) const { return FitSgmExtra->Eval(betagamma); } -AlgData::AlgData(){ +double AlgData::get_MeanExtra1(double betagamma) const { return FitMeanExtra1->Eval(betagamma); } - DataAlg=""; - data1=nullptr; - datalep=nullptr; - datahad=nullptr; - file=nullptr; +double AlgData::get_SgmExtra1(double betagamma) const { return FitSgmExtra1->Eval(betagamma); } +double AlgData::get_FracExtra1(double betagamma) const { return FitFracExtra1->Eval(betagamma); } - tmpCorrmeanSliceTot=nullptr; - tmpErrCorrmeanSliceTot=nullptr; - tmpCorrsgmSliceTot=nullptr; - tmpErrCorrsgmSliceTot=nullptr; +double AlgData::get_SlopeExtra1(double betagamma) const { return FitSlopeExtra1->Eval(betagamma); } - tmpCorrdglfracSliceTot=nullptr; - tmpErrCorrdglfracSliceTot=nullptr; - tmpCorrdglmeangSliceTot=nullptr; - tmpErrCorrdglmeangSliceTot=nullptr; - tmpCorrdglsgmgSliceTot=nullptr; - tmpErrCorrdglsgmgSliceTot=nullptr; - tmpCorrdglmpvSliceTot=nullptr; - tmpErrCorrdglmpvSliceTot=nullptr; - tmpCorrdglsgmlSliceTot=nullptr; - tmpErrCorrdglsgmlSliceTot=nullptr; +ROOT::Math::Interpolator* AlgData::Interpvalue(std::vector bg, std::vector Ydata, int Intertype) { + //tipo di interpolazione 0=linear;1=pol;2=cspline;4=akima + return itp1 = new ROOT::Math::Interpolator(bg, Ydata, (ROOT::Math::Interpolation::Type)Intertype); +} + +void AlgData::Load_interp() { + itpm["maxEx0Tot"] = Interpvalue(bgv, maxEx0Tot, 4); + itpm["tFfracTot"] = Interpvalue(bgv, tFfracTot, 4); + itpm["tFmpv1Tot"] = Interpvalue(bgv, tFmpv1Tot, 4); + itpm["tFsgm1Tot"] = Interpvalue(bgv, tFsgm1Tot, 4); + itpm["tFmpv2Tot"] = Interpvalue(bgv, tFmpv2Tot, 4); + itpm["tFsgm2Tot"] = Interpvalue(bgv, tFsgm2Tot, 4); + + itpm["CorrIntTot"] = Interpvalue(bgv, CorrIntTot, 4); + itpm["CorrSlpTot"] = Interpvalue(bgv, CorrSlpTot, 4); + for (unsigned int i = 0; i < tmpCorrmeanSliceTot->size(); ++i) { + TString nameCm = "CorrmeanSliceTot"; + TString nameCs = "CorrsgmSliceTot"; + Corrmean.push_back(nameCm + i); + Corrsgm.push_back(nameCs + i); + itpm[Corrmean.at(i)] = Interpvalue(bgv, CorrmeanSliceTot[i], 4); + itpm[Corrsgm.at(i)] = Interpvalue(bgv, CorrsgmSliceTot[i], 4); + } + + for (unsigned int j = 0; j < tmpCorrdglfracSliceTot->size(); ++j) { + TString nameCdf = "Corrdglfrac"; + TString nameCdm = "Corrdglmeang"; + TString nameCds = "Corrdglsgmg"; + TString nameCdmpv = "Corrdglmpv"; + TString nameCdsgl = "Corrdglsgmgl"; + Corrdglfrac.push_back(nameCdf + j); + Corrdglmeang.push_back(nameCdm + j); + Corrdglsgmg.push_back(nameCds + j); + Corrdglmpv.push_back(nameCdmpv + j); + Corrdglsgml.push_back(nameCdsgl + j); + itpm[Corrdglfrac.at(j)] = Interpvalue(bgv, CorrdglfracSliceTot[j], 4); + itpm[Corrdglmeang.at(j)] = Interpvalue(bgv, CorrdglmeangSliceTot[j], 4); + itpm[Corrdglsgmg.at(j)] = Interpvalue(bgv, CorrdglsgmgSliceTot[j], 4); + itpm[Corrdglmpv.at(j)] = Interpvalue(bgv, CorrdglmpvSliceTot[j], 4); + itpm[Corrdglsgml.at(j)] = Interpvalue(bgv, CorrdglsgmlSliceTot[j], 4); + } + + for (unsigned int n = 0; n < tmpCorrdgmeanSliceTot->size(); ++n) { + TString nameCdmg = "Corrdgmean"; + TString nameCdsgg = "Corrdgsgm"; + Corrdgmean.push_back(nameCdmg + n); + Corrdgsgm.push_back(nameCdsgg + n); + itpm[Corrdgmean.at(n)] = Interpvalue(bgv, CorrdgmeanSliceTot[n], 4); + itpm[Corrdgsgm.at(n)] = Interpvalue(bgv, CorrdgsgmSliceTot[n], 4); + } +} - tmpCorrdgmeanSliceTot=nullptr; - tmpErrCorrdgmeanSliceTot=nullptr; - tmpCorrdgsgmSliceTot=nullptr; - tmpErrCorrdgsgmSliceTot=nullptr; +double AlgData::get_maxEx0(double betagamma) { return itpm["maxEx0Tot"]->Eval(betagamma); } +double AlgData::get_Ffrac(double betagamma) { return itpm["tFfracTot"]->Eval(betagamma); } +double AlgData::get_Fmpv1(double betagamma) { return itpm["tFmpv1Tot"]->Eval(betagamma); } +double AlgData::get_Fsgm1(double betagamma) { return itpm["tFsgm1Tot"]->Eval(betagamma); } +double AlgData::get_Fmpv2(double betagamma) { return itpm["tFmpv2Tot"]->Eval(betagamma); } +double AlgData::get_Fsgm2(double betagamma) { return itpm["tFsgm2Tot"]->Eval(betagamma); } +double AlgData::get_ClSzCorrInt(double betagamma) { return itpm["CorrIntTot"]->Eval(betagamma); } +double AlgData::get_ClSzCorrSlp(double betagamma) { return itpm["CorrSlpTot"]->Eval(betagamma); } + +std::vector AlgData::get_ClSzCorrpmean(double betagamma) { + ClSzCorrpmean.clear(); + // std::cout<<"size "<size()<size(); ++i) { + ClSzCorrpmean.push_back(itpm[Corrmean.at(i)]->Eval(betagamma)); + } + + return ClSzCorrpmean; +} - Ft=nullptr; - FtFormula=nullptr; - FitMPVExtra=nullptr; - FitSgmExtra=nullptr; - FitMeanExtra1=nullptr; - FitSgmExtra1=nullptr; - FitSlopeExtra1=nullptr; - FitFracExtra1=nullptr; +std::vector AlgData::get_ClSzCorrpsgm(double betagamma) { + ClSzCorrpsgm.clear(); + for (unsigned int i = 0; i < tmpCorrmeanSliceTot->size(); ++i) { + ClSzCorrpsgm.push_back(itpm[Corrsgm.at(i)]->Eval(betagamma)); + } + return ClSzCorrpsgm; +} + +std::vector AlgData::get_ClSzCorrdglfrac(double betagamma) { + ClSzCorrdglfrac.clear(); + for (unsigned int i = 0; i < tmpCorrdglfracSliceTot->size(); ++i) { + ClSzCorrdglfrac.push_back(itpm[Corrdglfrac.at(i)]->Eval(betagamma)); + } + return ClSzCorrdglfrac; +} + +std::vector AlgData::get_ClSzCorrdglmeang(double betagamma) { + ClSzCorrdglmeang.clear(); + for (unsigned int i = 0; i < tmpCorrdglfracSliceTot->size(); ++i) { + ClSzCorrdglmeang.push_back(itpm[Corrdglmeang.at(i)]->Eval(betagamma)); + } + return ClSzCorrdglmeang; +} + +std::vector AlgData::get_ClSzCorrdglsgmg(double betagamma) { + ClSzCorrdglsgmg.clear(); + for (unsigned int i = 0; i < tmpCorrdglfracSliceTot->size(); ++i) { + ClSzCorrdglsgmg.push_back(itpm[Corrdglsgmg.at(i)]->Eval(betagamma)); + } + return ClSzCorrdglsgmg; +} + +std::vector AlgData::get_ClSzCorrdglmpvl(double betagamma) { + ClSzCorrdglmpvl.clear(); + for (unsigned int i = 0; i < tmpCorrdglfracSliceTot->size(); ++i) { + ClSzCorrdglmpvl.push_back(itpm[Corrdglmpv.at(i)]->Eval(betagamma)); + } + return ClSzCorrdglmpvl; +} + +std::vector AlgData::get_ClSzCorrdglsgml(double betagamma) { + ClSzCorrdglsgml.clear(); + for (unsigned int i = 0; i < tmpCorrdglfracSliceTot->size(); ++i) { + ClSzCorrdglsgml.push_back(itpm[Corrdglsgml.at(i)]->Eval(betagamma)); + } + return ClSzCorrdglsgml; +} + +std::vector AlgData::get_ClSzCorrdgmean(double betagamma) { + ClSzCorrdgmean.clear(); + for (unsigned int i = 0; i < tmpCorrdgmeanSliceTot->size(); ++i) { + ClSzCorrdgmean.push_back(itpm[Corrdgmean.at(i)]->Eval(betagamma)); + } + return ClSzCorrdgmean; +} + +std::vector AlgData::get_ClSzCorrdgsgm(double betagamma) { + ClSzCorrdgsgm.clear(); + for (unsigned int i = 0; i < tmpCorrdgmeanSliceTot->size(); ++i) { + ClSzCorrdgsgm.push_back(itpm[Corrdgsgm.at(i)]->Eval(betagamma)); + } + return ClSzCorrdgsgm; +} + +double AlgData::get_maxExSlp() { return maxExSlp; } + +void AlgData::Calc_maxExSlp() { + double sum = 0.0; + for (unsigned int i = 0; i < maxExSlpTot.size(); ++i) { + sum += maxExSlpTot[i]; + } + maxExSlp = sum / (double)maxExSlpTot.size(); +} + +double AlgData::get_ExSgmlep() { return ExSgmlep; } + +void AlgData::Calc_ExSgmlep() { + double sum = 0.0; + for (unsigned int i = 0; i < ExSgmTotlep.size(); ++i) { + sum += ExSgmTotlep[i]; + } + ExSgmlep = sum / (double)ExSgmTotlep.size(); +} +double AlgData::get_ExSgmhad() { return ExSgmhad; } +void AlgData::Calc_ExSgmhad() { + double sum = 0.0; + for (unsigned int i = 0; i < ExSgmTothad.size(); ++i) { + sum += ExSgmTothad[i]; + } + ExSgmhad = sum / (double)ExSgmTothad.size(); } - AlgData::~AlgData(){ - if(file->IsOpen())file->Close(); - } - - - void AlgData::read_file(TString dataAlg){ - - DataAlg=dataAlg; - - std::cout<<" ---reading of---"<Add(dataAlg.Data()); - datalep->Add(dataAlg.Data()); - datahad->Add(dataAlg.Data()); - - } - - data1->SetBranchAddress("bgT",&bgT); - data1->SetBranchAddress("tmpmaxEx0Tot",&tmpmaxEx0Tot); - data1->SetBranchAddress("tmpErrmaxEx0Tot",&tmpErrmaxEx0Tot); - data1->SetBranchAddress("tmpmaxExSlpTot",&tmpmaxExSlpTot); - data1->SetBranchAddress("tmpErrmaxExSlpTot",&tmpErrmaxExSlpTot); - data1->SetBranchAddress("tmptFfracTot",&tmptFfracTot); - data1->SetBranchAddress("tFerrfracTot",&tmptFerrfracTot); - data1->SetBranchAddress("tmptFerrfracTot",&tmptFmpv1Tot); - data1->SetBranchAddress("tmptFerrmpv1Tot",&tmptFerrmpv1Tot); - data1->SetBranchAddress("tmptFerrmpv1Tot",&tmptFerrmpv1Tot); - data1->SetBranchAddress("tmptFsgm1Tot",&tmptFsgm1Tot); - data1->SetBranchAddress("tmptFerrsgm1Tot",&tmptFerrsgm1Tot); - data1->SetBranchAddress("tmptFmpv2Tot",&tmptFmpv2Tot); - data1->SetBranchAddress("tmptFerrmpv2Tot",&tmptFerrmpv2Tot); - data1->SetBranchAddress("tmptFsgm2Tot",&tmptFsgm2Tot); - data1->SetBranchAddress("tmptFerrsgm2Tot",&tmptFerrsgm2Tot); - - data1->SetBranchAddress("tmpCorrIntTot",&tmpCorrIntTot); - data1->SetBranchAddress("tmpErrCorrIntTot",&tmpErrCorrIntTot); - data1->SetBranchAddress("tmpCorrSlpTot",&tmpCorrSlpTot); - data1->SetBranchAddress("tmpErrCorrSlpTot",&tmpErrCorrSlpTot); - - data1->SetBranchAddress("tmpCorrmeanSliceTot",&tmpCorrmeanSliceTot); - data1->SetBranchAddress("tmpErrCorrmeanSliceTot",&tmpErrCorrmeanSliceTot); - data1->SetBranchAddress("tmpCorrsgmSliceTot",&tmpCorrsgmSliceTot); - data1->SetBranchAddress("tmpErrCorrsgmSliceTot",&tmpErrCorrsgmSliceTot); - - data1->SetBranchAddress("tmpCorrdgmeanSliceTot",&tmpCorrdgmeanSliceTot); - data1->SetBranchAddress("tmpErrCorrdgmeanSliceTot",&tmpErrCorrdgmeanSliceTot); - data1->SetBranchAddress("tmpCorrdgsgmSliceTot",&tmpCorrdgsgmSliceTot); - data1->SetBranchAddress("tmpErrCorrdgsgmSliceTot",&tmpErrCorrdgsgmSliceTot); - - data1->SetBranchAddress("tmpCorrdglfracSliceTot",&tmpCorrdglfracSliceTot); - data1->SetBranchAddress("tmpErrCorrdglfracSliceTot",&tmpErrCorrdglfracSliceTot); - data1->SetBranchAddress("tmpCorrdglmeangSliceTot",&tmpCorrdglmeangSliceTot); - data1->SetBranchAddress("tmpErrCorrdglmeangSliceTot",&tmpErrCorrdglmeangSliceTot); - data1->SetBranchAddress("tmpCorrdglsgmgSliceTot",&tmpCorrdglsgmgSliceTot); - data1->SetBranchAddress("tmpErrCorrdglsgmgSliceTot",&tmpErrCorrdglsgmgSliceTot); - data1->SetBranchAddress("tmpCorrdglmpvSliceTot",&tmpCorrdglmpvSliceTot); - data1->SetBranchAddress("tmpErrCorrdglmpvSliceTot",&tmpErrCorrdglmpvSliceTot); - data1->SetBranchAddress("tmpCorrdglsgmlSliceTot",&tmpCorrdglsgmlSliceTot); - data1->SetBranchAddress("tmpErrCorrdglsgmlSliceTot",&tmpErrCorrdglsgmlSliceTot); - - datalep->SetBranchAddress("bgTlep",&bgTlep); - datalep->SetBranchAddress("tmpExSgmTotlep",&tmpExSgmTotlep); - - datahad->SetBranchAddress("bgThad",&bgThad); - datahad->SetBranchAddress("tmpExSgmTothad",&tmpExSgmTothad); - - - for (int i=0;iGetEntries();i++) { - data1->GetEntry(i); - bgv.push_back(bgT); -// std::cout<size();++j){ - CorrmeanSliceTot[j].push_back(tmpCorrmeanSliceTot->at(j)); - ErrCorrmeanSliceTot[j].push_back(tmpErrCorrmeanSliceTot->at(j)); - CorrsgmSliceTot[j].push_back(tmpCorrsgmSliceTot->at(j)); - ErrCorrsgmSliceTot[j].push_back(tmpErrCorrsgmSliceTot->at(j)); - } - - for( unsigned int n=0;nsize();++n){ - CorrdgmeanSliceTot[n].push_back(tmpCorrdgmeanSliceTot->at(n)); - ErrCorrdgmeanSliceTot[n].push_back(tmpErrCorrdgmeanSliceTot->at(n)); - CorrdgsgmSliceTot[n].push_back(tmpCorrdgsgmSliceTot->at(n)); - ErrCorrdgsgmSliceTot[n].push_back(tmpErrCorrdgsgmSliceTot->at(n)); - } - - for(unsigned int k=0;ksize();++k){ - CorrdglfracSliceTot[k].push_back(tmpCorrdglfracSliceTot->at(k)); - ErrCorrdglfracSliceTot[k].push_back(tmpErrCorrdglfracSliceTot->at(k)); - CorrdglmeangSliceTot[k].push_back(tmpCorrdglmeangSliceTot->at(k)); - ErrCorrdglmeangSliceTot[k].push_back(tmpErrCorrdglmeangSliceTot->at(k)); - CorrdglsgmgSliceTot[k].push_back(tmpCorrdglsgmgSliceTot->at(k)); - ErrCorrdglsgmgSliceTot[k].push_back(tmpErrCorrdglsgmgSliceTot->at(k)); - CorrdglmpvSliceTot[k].push_back(tmpCorrdglmpvSliceTot->at(k)); - ErrCorrdglmpvSliceTot[k].push_back(tmpErrCorrdglmpvSliceTot->at(k)); - CorrdglsgmlSliceTot[k].push_back(tmpCorrdglsgmlSliceTot->at(k)); - ErrCorrdglsgmlSliceTot[k].push_back(tmpErrCorrdglsgmlSliceTot->at(k)); -// std::cout<at(k)<GetEntries();i++) { - datalep->GetEntry(i); - bglep.push_back(bgTlep); - ExSgmTotlep.push_back(tmpExSgmTotlep); -// std::cout<< " bgTlep "<GetEntries();i++) { - datahad->GetEntry(i); - bghad.push_back(bgThad); - ExSgmTothad.push_back(tmpExSgmTothad); - } - - } - - - - TF1* AlgData::read_graph(TString dataAlg, TString cvName, TString fitName){ - DataAlg=dataAlg; - file = TFile::Open(dataAlg.Data(),"read"); - TCanvas *cv=(TCanvas *)file->Get(cvName.Data()); - TGraph *gr=(TGraph *)cv->GetListOfPrimitives()->FindObject("Graph"); - TF1* ft=(TF1*)gr->GetListOfFunctions()->FindObject(fitName.Data()); - TFormula *ftFormula=(TFormula *)ft->GetFormula(); - FtFormula=ftFormula; - return ft; - } - - void AlgData::Load_file(TString dataAlg){ - read_file(dataAlg.Data()); - FitMPVExtra=read_graph(dataAlg.Data(), "cMPVExtrabgTot", "fit_MPV"); - FitSgmExtra=read_graph(dataAlg.Data(), "cSgmExtrabgTot", "fit_sgmEx"); - FitMeanExtra1=read_graph(dataAlg.Data(), "cMeanExtra1bgTot", "expeff"); - FitSgmExtra1=read_graph(dataAlg.Data(), "cSgmExtra1bgTot", "expeffNeg"); - FitSlopeExtra1=read_graph(dataAlg.Data(), "cSlopeExtra1bgTot", "fit_slp"); - FitFracExtra1=read_graph(dataAlg.Data(), "cfracbgTot", "fit_frEx"); - Calc_ExSgmhad(); - Calc_ExSgmlep(); - Calc_maxExSlp(); - } - - TF1* AlgData::get_fit(){ - return Ft; - } - - TFormula * AlgData::get_formula(){ - return FtFormula; - } - - double AlgData::get_MPVExtra (double betagamma) const{ - return FitMPVExtra->Eval(betagamma); - } - - double AlgData::get_SgmExtra(double betagamma) const{ - return FitSgmExtra->Eval(betagamma); - } - - double AlgData::get_MeanExtra1(double betagamma) const{ - return FitMeanExtra1->Eval(betagamma); - } - - double AlgData::get_SgmExtra1(double betagamma) const{ - return FitSgmExtra1->Eval(betagamma); - } - - double AlgData::get_FracExtra1(double betagamma) const{ - return FitFracExtra1->Eval(betagamma); - } - - double AlgData::get_SlopeExtra1(double betagamma) const{ - return FitSlopeExtra1->Eval(betagamma); - } - - - ROOT::Math::Interpolator* AlgData::Interpvalue(std::vectorbg,std::vectorYdata,int Intertype) { - //tipo di interpolazione 0=linear;1=pol;2=cspline;4=akima - return itp1=new ROOT::Math::Interpolator(bg,Ydata,(ROOT::Math::Interpolation::Type)Intertype); - } - - void AlgData::Load_interp(){ - itpm["maxEx0Tot"]=Interpvalue(bgv,maxEx0Tot,4); - itpm["tFfracTot"]=Interpvalue(bgv,tFfracTot,4); - itpm["tFmpv1Tot"]=Interpvalue(bgv,tFmpv1Tot,4); - itpm["tFsgm1Tot"]=Interpvalue(bgv,tFsgm1Tot,4); - itpm["tFmpv2Tot"]=Interpvalue(bgv,tFmpv2Tot,4); - itpm["tFsgm2Tot"]=Interpvalue(bgv,tFsgm2Tot,4); - - itpm["CorrIntTot"]=Interpvalue(bgv,CorrIntTot,4); - itpm["CorrSlpTot"]=Interpvalue(bgv,CorrSlpTot,4); - for(unsigned int i=0;isize();++i){ - TString nameCm="CorrmeanSliceTot"; - TString nameCs="CorrsgmSliceTot"; - Corrmean.push_back(nameCm+i); - Corrsgm.push_back(nameCs+i); - itpm[Corrmean.at(i)]=Interpvalue(bgv, CorrmeanSliceTot[i], 4); - itpm[Corrsgm.at(i)]=Interpvalue(bgv, CorrsgmSliceTot[i], 4); - - } - - for(unsigned int j=0;jsize();++j){ - TString nameCdf="Corrdglfrac"; - TString nameCdm="Corrdglmeang"; - TString nameCds="Corrdglsgmg"; - TString nameCdmpv="Corrdglmpv"; - TString nameCdsgl="Corrdglsgmgl"; - Corrdglfrac.push_back(nameCdf+j); - Corrdglmeang.push_back(nameCdm+j); - Corrdglsgmg.push_back(nameCds+j); - Corrdglmpv.push_back(nameCdmpv+j); - Corrdglsgml.push_back(nameCdsgl+j); - itpm[Corrdglfrac.at(j)]=Interpvalue(bgv, CorrdglfracSliceTot[j], 4); - itpm[Corrdglmeang.at(j)]=Interpvalue(bgv, CorrdglmeangSliceTot[j], 4); - itpm[Corrdglsgmg.at(j)]=Interpvalue(bgv, CorrdglsgmgSliceTot[j], 4); - itpm[Corrdglmpv.at(j)]=Interpvalue(bgv, CorrdglmpvSliceTot[j], 4); - itpm[Corrdglsgml.at(j)]=Interpvalue(bgv, CorrdglsgmlSliceTot[j], 4); - } - - for(unsigned int n=0;nsize();++n){ - TString nameCdmg="Corrdgmean"; - TString nameCdsgg="Corrdgsgm"; - Corrdgmean.push_back(nameCdmg+n); - Corrdgsgm.push_back(nameCdsgg+n); - itpm[Corrdgmean.at(n)]=Interpvalue(bgv, CorrdgmeanSliceTot[n], 4); - itpm[Corrdgsgm.at(n)]=Interpvalue(bgv, CorrdgsgmSliceTot[n], 4); - } - } - - double AlgData::get_maxEx0(double betagamma) { - return itpm["maxEx0Tot"]->Eval(betagamma); - } - double AlgData::get_Ffrac(double betagamma) { - return itpm["tFfracTot"]->Eval(betagamma); - } - double AlgData::get_Fmpv1(double betagamma) { - return itpm["tFmpv1Tot"]->Eval(betagamma); - } - double AlgData::get_Fsgm1(double betagamma) { - return itpm["tFsgm1Tot"]->Eval(betagamma); - } - double AlgData::get_Fmpv2(double betagamma) { - return itpm["tFmpv2Tot"]->Eval(betagamma); - } - double AlgData::get_Fsgm2(double betagamma) { - return itpm["tFsgm2Tot"]->Eval(betagamma); - } - double AlgData::get_ClSzCorrInt(double betagamma){ - return itpm["CorrIntTot"]->Eval(betagamma); - } - double AlgData::get_ClSzCorrSlp(double betagamma){ - return itpm["CorrSlpTot"]->Eval(betagamma); - } - - std::vector AlgData::get_ClSzCorrpmean(double betagamma){ - ClSzCorrpmean.clear(); -// std::cout<<"size "<size()<size();++i){ - ClSzCorrpmean.push_back(itpm[Corrmean.at(i)]->Eval(betagamma)); - } - - return ClSzCorrpmean; - } - - std::vector AlgData::get_ClSzCorrpsgm(double betagamma){ - ClSzCorrpsgm.clear(); - for(unsigned int i=0;isize();++i){ - ClSzCorrpsgm.push_back(itpm[Corrsgm.at(i)]->Eval(betagamma)); - } - return ClSzCorrpsgm; - } - - std::vector AlgData::get_ClSzCorrdglfrac(double betagamma){ - ClSzCorrdglfrac.clear(); - for(unsigned int i=0;isize();++i){ - ClSzCorrdglfrac.push_back(itpm[Corrdglfrac.at(i)]->Eval(betagamma)); - } - return ClSzCorrdglfrac; - } - - std::vector AlgData::get_ClSzCorrdglmeang(double betagamma){ - ClSzCorrdglmeang.clear(); - for(unsigned int i=0;isize();++i){ - ClSzCorrdglmeang.push_back(itpm[Corrdglmeang.at(i)]->Eval(betagamma)); - } - return ClSzCorrdglmeang; - } - - std::vector AlgData::get_ClSzCorrdglsgmg(double betagamma){ - ClSzCorrdglsgmg.clear(); - for(unsigned int i=0;isize();++i){ - ClSzCorrdglsgmg.push_back(itpm[Corrdglsgmg.at(i)]->Eval(betagamma)); - } - return ClSzCorrdglsgmg; - } - - std::vector AlgData::get_ClSzCorrdglmpvl(double betagamma){ - ClSzCorrdglmpvl.clear(); - for(unsigned int i=0;isize();++i){ - ClSzCorrdglmpvl.push_back(itpm[Corrdglmpv.at(i)]->Eval(betagamma)); - } - return ClSzCorrdglmpvl; - } - - std::vector AlgData::get_ClSzCorrdglsgml(double betagamma){ - ClSzCorrdglsgml.clear(); - for(unsigned int i=0;isize();++i){ - ClSzCorrdglsgml.push_back(itpm[Corrdglsgml.at(i)]->Eval(betagamma)); - } - return ClSzCorrdglsgml; - } - - std::vector AlgData::get_ClSzCorrdgmean(double betagamma){ - ClSzCorrdgmean.clear(); - for(unsigned int i=0;isize();++i){ - ClSzCorrdgmean.push_back(itpm[Corrdgmean.at(i)]->Eval(betagamma)); - } - return ClSzCorrdgmean; - } - - std::vector AlgData::get_ClSzCorrdgsgm(double betagamma){ - ClSzCorrdgsgm.clear(); - for(unsigned int i=0;isize();++i){ - ClSzCorrdgsgm.push_back(itpm[Corrdgsgm.at(i)]->Eval(betagamma)); - } - return ClSzCorrdgsgm; - } - - - double AlgData::get_maxExSlp(){ - return maxExSlp; - } - - void AlgData::Calc_maxExSlp(){ - double sum=0.0; - for(unsigned int i=0;i #include +#include // data extension for the DCH v2 #include "DDRec/DCH_info.h" // ROOT headers -#include "TVector3.h" -#include "TRandom3.h" #include "TFile.h" #include "TH1D.h" +#include "TRandom3.h" +#include "TVector3.h" // Class developed by Walaa for the CLS #include "AlgData.h" @@ -78,20 +76,17 @@ constexpr double MM_TO_CM = 0.1; struct DCHdigi final : k4FWCore::MultiTransformer< - std::tuple( + std::tuple( const edm4hep::SimTrackerHitCollection&, const edm4hep::EventHeaderCollection&)> { DCHdigi(const std::string& name, ISvcLocator* svcLoc); StatusCode initialize() override; StatusCode finalize() override; - std::tuple operator()( - const edm4hep::SimTrackerHitCollection& , - const edm4hep::EventHeaderCollection& ) const override; + std::tuple + operator()(const edm4hep::SimTrackerHitCollection&, const edm4hep::EventHeaderCollection&) const override; private: - - //------------------------------------------------------------------ // machinery for geometry @@ -103,29 +98,30 @@ struct DCHdigi final Gaudi::Property m_DCH_name{this, "DCH_name", "DCH_v2", "Name of the Drift Chamber detector"}; /// Pointer to the geometry service - SmartIF m_geoSvc; + SmartIF m_geoSvc; /// Decoder for the cellID dd4hep::DDSegmentation::BitFieldCoder* m_decoder; /// Pointer to drift chamber data extension - dd4hep::rec::DCH_info * dch_data = {nullptr}; + dd4hep::rec::DCH_info* dch_data = {nullptr}; //------------------------------------------------------------------ // machinery for smearing the position /// along the sense wire position resolution in mm - Gaudi::Property m_z_resolution{this, "zResolution_mm", 1.0, - "Spatial resolution in the z direction (from reading out the wires at both sides) in mm. Default 1 mm."}; + Gaudi::Property m_z_resolution{ + this, "zResolution_mm", 1.0, + "Spatial resolution in the z direction (from reading out the wires at both sides) in mm. Default 1 mm."}; /// xy resolution in mm - Gaudi::Property m_xy_resolution{this, "xyResolution_mm", 0.1, "Spatial resolution in the xy direction in mm. Default 0.1 mm."}; + Gaudi::Property m_xy_resolution{this, "xyResolution_mm", 0.1, + "Spatial resolution in the xy direction in mm. Default 0.1 mm."}; /// create seed using the uid - SmartIF m_uidSvc; + SmartIF m_uidSvc; /// use thread local engine from C++ standard inline static thread_local std::mt19937_64 m_engine; - void PrepareRandomEngine(const edm4hep::EventHeaderCollection& headers) const; - + void PrepareRandomEngine(const edm4hep::EventHeaderCollection& headers) const; // Operator std::normal_distribution::operator()(Generator& g) is a non-const member function and thus cannot be called for a constant object. So we defined the distribution as mutable. // Gaussian random number generator used for the smearing of the z position, in cm! @@ -137,7 +133,7 @@ struct DCHdigi final //------------------------------------------------------------------ // ancillary functions - bool IsFileGood(std::string & ifilename) const {return std::ifstream(ifilename).good(); } + bool IsFileGood(std::string& ifilename) const { return std::ifstream(ifilename).good(); } /// Print algorithm configuration void PrintConfiguration(std::ostream& io); @@ -146,60 +142,60 @@ struct DCHdigi final void ThrowException(std::string s) const; int CalculateLayerFromCellID(dd4hep::DDSegmentation::CellID id) const { - return m_decoder->get ( id,"layer" ) + dch_data->nlayersPerSuperlayer*m_decoder->get ( id,"superlayer" ) + 1; + return m_decoder->get(id, "layer") + dch_data->nlayersPerSuperlayer * m_decoder->get(id, "superlayer") + 1; } - int CalculateNphiFromCellID(dd4hep::DDSegmentation::CellID id) const { - return m_decoder->get ( id,"nphi" ); - } + int CalculateNphiFromCellID(dd4hep::DDSegmentation::CellID id) const { return m_decoder->get(id, "nphi"); } - TVector3 Convert_EDM4hepVector_to_TVector3(const edm4hep::Vector3d & v, double scale) const { - return {v[0]*scale,v[1]*scale,v[2]*scale}; + TVector3 Convert_EDM4hepVector_to_TVector3(const edm4hep::Vector3d& v, double scale) const { + return {v[0] * scale, v[1] * scale, v[2] * scale}; }; - edm4hep::Vector3d Convert_TVector3_to_EDM4hepVector(const TVector3 & v, double scale) const{ - return {v.x()*scale,v.y()*scale,v.z()*scale}; + edm4hep::Vector3d Convert_TVector3_to_EDM4hepVector(const TVector3& v, double scale) const { + return {v.x() * scale, v.y() * scale, v.z() * scale}; }; // the following functions should be upstreamed to the data extension at DD4hep // to avoid code duplication and keep it centralized - TVector3 Calculate_hitpos_to_wire_vector(int ilayer, int nphi, const TVector3 & hit_position /*in cm*/) const; - TVector3 Calculate_wire_vector_ez (int ilayer, int nphi) const; - TVector3 Calculate_wire_z0_point (int ilayer, int nphi) const; - double Calculate_wire_phi_z0 (int ilayer, int nphi) const; - + TVector3 Calculate_hitpos_to_wire_vector(int ilayer, int nphi, const TVector3& hit_position /*in cm*/) const; + TVector3 Calculate_wire_vector_ez(int ilayer, int nphi) const; + TVector3 Calculate_wire_z0_point(int ilayer, int nphi) const; + double Calculate_wire_phi_z0(int ilayer, int nphi) const; //------------------------------------------------------------------ // cluster calculation, developed by Walaa /// file with distributions to be sampled - Gaudi::Property m_fileDataAlg{this, "fileDataAlg", "/eos/project/f/fccsw-web/www/filesForSimDigiReco/IDEA/DataAlgFORGEANT.root", "ROOT file with cluster size distributions"}; + Gaudi::Property m_fileDataAlg{ + this, "fileDataAlg", "/eos/project/f/fccsw-web/www/filesForSimDigiReco/IDEA/DataAlgFORGEANT.root", + "ROOT file with cluster size distributions"}; /// pointer to wrapper class, which contains the cluster size and number distributions - AlgData * flData; + AlgData* flData; /// code developed by Walaa for calculating number of clusters and cluster size - std::pair CalculateClusters(const edm4hep::SimTrackerHit & input_sim_hit) const; + std::pair CalculateClusters(const edm4hep::SimTrackerHit& input_sim_hit) const; //------------------------------------------------------------------ // debug information /// Flag to create output file with debug histgrams - Gaudi::Property m_create_debug_histos{this, "create_debug_histograms", false, "Create output file with histograms for debugging"}; - + Gaudi::Property m_create_debug_histos{this, "create_debug_histograms", false, + "Create output file with histograms for debugging"}; + /// name for the file that will contain the histograms for debugging - Gaudi::Property m_out_debug_filename{this, "out_debug_filename", "dch_digi_alg_debug.root", "name for the file that will contain the histograms for debugging"}; + Gaudi::Property m_out_debug_filename{this, "out_debug_filename", "dch_digi_alg_debug.root", + "name for the file that will contain the histograms for debugging"}; /// histogram to store distance from hit position to the wire - TH1D * hDpw; + TH1D* hDpw; /// histogram to store distance from hit projection to the wire (should be zero) - TH1D * hDww; + TH1D* hDww; /// histogram to store smearing along the wire - TH1D * hSz; + TH1D* hSz; /// histogram to store smearing perpendicular the wire - TH1D * hSxy; - + TH1D* hSxy; }; DECLARE_COMPONENT(DCHdigi); diff --git a/DCHdigi/src/DCHdigi.cpp b/DCHdigi/src/DCHdigi.cpp index a83e611..e69de29 100644 --- a/DCHdigi/src/DCHdigi.cpp +++ b/DCHdigi/src/DCHdigi.cpp @@ -1,664 +0,0 @@ -#include "DCHdigi.h" - -// STL -#include -#include - -#include "extension/MutableDriftChamberDigiV2.h" - -/////////////////////////////////////////////////////////////////////////////////////// -/////////////////////// DCHdigi constructor //////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////// -// -- KeyValues("name of the variable that holds the name of the collection exposed in the python steering file", {"default name for the collection"}), -DCHdigi::DCHdigi(const std::string& name, ISvcLocator* svcLoc) -: MultiTransformer(name, svcLoc, - { - KeyValues("DCH_simhits", {""}), - KeyValues("HeaderName", {"EventHeader"}), - }, - { - KeyValues("DCH_DigiCollection", {"DCH_DigiCollection"}), - KeyValues("DCH_DigiSimAssociationCollection", {"DCH_DigiSimAssociationCollection"}) - } - ) -{ - m_geoSvc = serviceLocator()->service(m_geoSvcName); - m_uidSvc = serviceLocator()->service(m_uidSvcName); -} - -/////////////////////////////////////////////////////////////////////////////////////// -/////////////////////// initialize //////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////// -StatusCode DCHdigi::initialize() { - - if (!m_uidSvc) - ThrowException( "Unable to get UniqueIDGenSvc" ); - - m_gauss_z_cm = std::normal_distribution(0., m_z_resolution.value()*MM_TO_CM ); - m_gauss_xy_cm = std::normal_distribution(0., m_xy_resolution.value()*MM_TO_CM); - - //----------------- - // Retrieve the subdetector - std::string DCH_name(m_DCH_name.value()); - if ( 0 == m_geoSvc->getDetector()->detectors().count(DCH_name) ) - { - ThrowException( "Detector <<" + DCH_name + ">> does not exist." ); - } - - dd4hep::DetElement DCH_DE = m_geoSvc->getDetector()->detectors().at(DCH_name); - - /////////////////////////////////////////////////////////////////////////////////// - /////////////////////////// retrieve data extension ////////////////////////// - /////////////////////////////////////////////////////////////////////////////////// - this->dch_data = DCH_DE.extension(); - - /////////////////////////////////////////////////////////////////////////////////// - - //----------------- - // Retrieve the readout associated with the detector element (subdetector) - dd4hep::SensitiveDetector dch_sd = m_geoSvc->getDetector()->sensitiveDetector(DCH_name); - if(not dch_sd.isValid() ) - ThrowException("No valid Sensitive Detector was found for detector <<" + DCH_name + ">>."); - - dd4hep::Readout dch_readout = dch_sd.readout(); - // set the cellID decoder - m_decoder = dch_readout.idSpec().decoder(); - - /////////////////////////////////////////////////////////////////////////////////// - ////////////////// initialize Walaa's code for Cluster counting ///////////////// - /////////////////////////////////////////////////////////////////////////////////// - debug() << Form("Opening %s...",m_fileDataAlg.value().c_str())<> not found."); - flData = new AlgData(); - flData->Load_file(m_fileDataAlg.value().c_str()); - flData->Load_interp(); - debug() << Form("Opening %s... Done",m_fileDataAlg.value().c_str())<SetDirectory(0); - hDww = new TH1D("hDww", "Distance hit projection to the wire, in cm. Should be zero", 100,0,1); - hDww->SetDirectory(0); - hSz = new TH1D("hSz", "Smearing along the wire, in cm", 100,0,5*m_z_resolution.value()); - hSz->SetDirectory(0); - hSxy = new TH1D("hSxy", "Smearing perpendicular the wire, in cm", 100,0,5*m_xy_resolution.value()); - hSxy->SetDirectory(0); - } - return StatusCode::SUCCESS; - } - - - -/////////////////////////////////////////////////////////////////////////////////////// -/////////////////////// operator() //////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////// -std::tuple -DCHdigi::operator()(const edm4hep::SimTrackerHitCollection& input_sim_hits, - const edm4hep::EventHeaderCollection& headers) const { - - // initialize seed for random engine - this->PrepareRandomEngine( headers ); - - debug() << "Input Sim Hit collection size: " << input_sim_hits.size() << endmsg; - - // Create the collections we are going to return - extension::DriftChamberDigiV2Collection output_digi_hits; - extension::MCRecoDriftChamberDigiV2AssociationCollection output_digi_sim_association; - - //loop over hit collection - for (const auto& input_sim_hit : input_sim_hits) - { - dd4hep::DDSegmentation::CellID cellid = input_sim_hit.getCellID(); - int ilayer = this->CalculateLayerFromCellID(cellid ); - int nphi = this->CalculateNphiFromCellID(cellid ); - auto hit_position = Convert_EDM4hepVector_to_TVector3( input_sim_hit.getPosition(), MM_TO_CM ); - - // ------------------------------------------------------------------------- - // calculate hit position projection into the wire - TVector3 hit_to_wire_vector = this->Calculate_hitpos_to_wire_vector(ilayer, nphi,hit_position); - TVector3 hit_projection_on_the_wire = hit_position + hit_to_wire_vector; - if( m_create_debug_histos.value() ) - { - double distance_hit_wire = hit_to_wire_vector.Mag(); - hDpw->Fill(distance_hit_wire); - } - TVector3 wire_direction_ez = this->Calculate_wire_vector_ez(ilayer, nphi); - - // ------------------------------------------------------------------------- - // smear the position - - // smear position along the wire - double smearing_z = m_gauss_z_cm( m_engine ); - if( m_create_debug_histos.value() ) hSz->Fill( smearing_z ); - - hit_projection_on_the_wire += smearing_z*(wire_direction_ez.Unit()); - if( m_create_debug_histos.value() ) - { - // the distance from the hit projection and the wire should be zero - TVector3 dummy_vector = this->Calculate_hitpos_to_wire_vector(ilayer, nphi,hit_projection_on_the_wire); - hDww->Fill( dummy_vector.Mag() ); - } - - // smear position perpendicular to the wire - double smearing_xy = m_gauss_xy_cm( m_engine ); - if( m_create_debug_histos.value() ) hSxy->Fill( smearing_xy ); - float distanceToWire_real = hit_to_wire_vector.Mag(); - - // protect against negative values - float distanceToWire_smeared = std::max(0.0, distanceToWire_real +smearing_xy ); - - std::int32_t type = 0; - std::int32_t quality = 0; - float eDepError =0; - // length units back to mm - auto positionSW = Convert_TVector3_to_EDM4hepVector(hit_projection_on_the_wire, 1./MM_TO_CM ); - auto directionSW = Convert_TVector3_to_EDM4hepVector(wire_direction_ez , 1./MM_TO_CM ); - float distanceToWire = distanceToWire_smeared/MM_TO_CM; - - auto [nCluster,nElectronPerCluster] = CalculateClusters(input_sim_hit); - - extension::MutableDriftChamberDigiV2 oDCHdigihit; - oDCHdigihit.setCellID(input_sim_hit.getCellID()); - oDCHdigihit.setType(type); - oDCHdigihit.setQuality(quality); - oDCHdigihit.setTime(input_sim_hit.getTime()); - oDCHdigihit.setEDep(input_sim_hit.getEDep()); - oDCHdigihit.setEDepError(eDepError); - oDCHdigihit.setPosition(positionSW); - oDCHdigihit.setDirectionSW(directionSW); - oDCHdigihit.setDistanceToWire(distanceToWire); - oDCHdigihit.setNCluster(nCluster); - oDCHdigihit.setNElectronPerCluster(nElectronPerCluster); - - output_digi_hits.push_back(oDCHdigihit); - - extension::MutableMCRecoDriftChamberDigiV2Association oDCHsimdigi_association; - oDCHsimdigi_association.setDigi( oDCHdigihit ); - oDCHsimdigi_association.setSim( input_sim_hit ); - output_digi_sim_association.push_back(oDCHsimdigi_association); - - }// end loop over hit collection - - ///////////////////////////////////////////////////////////////// - return std::make_tuple(std::move(output_digi_hits),std::move(output_digi_sim_association)); -} - -/////////////////////////////////////////////////////////////////////////////////////// -/////////////////////// finalize ////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////// -StatusCode DCHdigi::finalize() -{ - if( m_create_debug_histos.value() ) - { - std::unique_ptr ofile{TFile::Open ( m_out_debug_filename.value().c_str() , "recreate" ) }; - ofile->cd(); - hDpw->Write(); - hDww->Write(); - hSxy->Write(); - hSz->Write(); - } - - return StatusCode::SUCCESS; -} - -/////////////////////////////////////////////////////////////////////////////////////// -/////////////////////// ThrowException //////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////// -void DCHdigi::ThrowException(std::string s) const { - error() << s.c_str() << endmsg; - throw std::runtime_error(s); - } - -/////////////////////////////////////////////////////////////////////////////////////// -/////////////////////// PrintConfiguration //////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////// -void DCHdigi::PrintConfiguration(std::ostream& io) -{ - io << "DCHdigi will use the following components:\n"; - io << "\tGeometry Service: " << m_geoSvcName.value().c_str() << "\n"; - io << "\tUID Service: " << m_uidSvcName.value().c_str() << "\n"; - io << "\tDetector name: " << m_DCH_name.value().c_str() << "\n"; - io << "\t\t|--Volume bitfield: " << m_decoder->fieldDescription().c_str() << "\n"; - io << "\t\t|--Number of layers: " << dch_data->database.size() << "\n"; - io << "\tCluster distributions taken from: " << m_fileDataAlg.value().c_str() << "\n"; - io << "\tResolution along the wire (mm): " << m_z_resolution.value() << "\n"; - io << "\tResolution perp. to the wire (mm): " << m_xy_resolution.value() << "\n"; - return; -} - -void DCHdigi::PrepareRandomEngine(const edm4hep::EventHeaderCollection& headers) const -{ - uint32_t evt_n = headers[0].getEventNumber(); - uint32_t run_n = headers[0].getRunNumber(); - size_t seed = m_uidSvc->getUniqueID(evt_n, run_n, this->name() ); - m_engine.seed(seed); - // advance internal state to minimize possibility of creating correlations - m_engine.discard(10); - for(int i=0; i<10; ++i) myRandom.Rndm(); -} - -/////////////////////////////////////////////////////////////////////////////////////// -///// Ancillary functions for calculating the distance to the wire //////// -/////////////////////////////////////////////////////////////////////////////////////// - - -TVector3 DCHdigi::Calculate_wire_vector_ez(int ilayer, int nphi) const -{ - auto & l = this->dch_data->database.at(ilayer); - - // See original paper Hoshina et al, Computer Physics Communications 153 (2003) 3 - // eq. 2.9, for the definition of ez, vector along the wire - - // initialize some variables - int stereosign = l.StereoSign(); - double rz0 = l.radius_sw_z0; - double dphi = dch_data->twist_angle; - // kappa is the same as in eq. 2.9 - double kappa = (1./dch_data->Lhalf)*tan(dphi/2); - - //--- calculating wire position - // the points p1 and p2 correspond to the ends of the wire - - // point 1 - // double x1 = rz0; // m - // double y1 = 0.; // m - // double z1 = 0.; // m - double x1 = rz0; // m - double y1 = -stereosign*rz0*kappa*dch_data->Lhalf; // m - double z1 = -dch_data->Lhalf; // m - - TVector3 p1 (x1,y1,z1); - - - // point 2 - double x2 = rz0; // m - double y2 = stereosign*rz0*kappa*dch_data->Lhalf; // m - double z2 = dch_data->Lhalf; // m - - TVector3 p2 (x2,y2,z2); - - // calculate phi rotation of whole twisted tube, ie, rotation at z=0 - double phi_z0 = Calculate_wire_phi_z0(ilayer,nphi); - p1.RotateZ(phi_z0); - p2.RotateZ(phi_z0); - - //--- end calculating wire position - - return (p2-p1).Unit(); - -} - -TVector3 DCHdigi::Calculate_wire_z0_point(int ilayer, int nphi) const -{ - auto & l = this->dch_data->database.at(ilayer); - double rz0 = l.radius_sw_z0; - TVector3 p1 (rz0,0,0); - double phi_z0 = Calculate_wire_phi_z0(ilayer,nphi); - p1.RotateZ(phi_z0); - return p1; -} - -// calculate phi rotation of whole twisted tube, ie, rotation at z=0 -double DCHdigi::Calculate_wire_phi_z0(int ilayer, int nphi) const -{ - auto & l = this->dch_data->database.at(ilayer); - int ncells = l.nwires/2; - double phistep = TMath::TwoPi()/ncells; - double phi_z0 = (nphi + 0.25*(l.layer%2))*phistep; - return phi_z0; -} - - -/////////////////////////////////////////////////////////////////////////////////////// -/////////////////////// Calculate vector from hit position to wire ///////////////// -/////////////////////////////////////////////////////////////////////////////////////// -TVector3 DCHdigi::Calculate_hitpos_to_wire_vector(int ilayer, int nphi, const TVector3 & hit_position /*in cm*/) const -{ - // Solution distance from a point to a line given here: - // https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line#Vector_formulation - TVector3 n = this->Calculate_wire_vector_ez(ilayer, nphi); - TVector3 a = this->Calculate_wire_z0_point (ilayer, nphi); - // Remember using cm as natural units of DD4hep consistently! - // TVector3 p {hit_position.x()*MM_TO_CM,hit_position.y()*MM_TO_CM,hit_position.z()*MM_TO_CM}; - - TVector3 a_minus_p = a - hit_position; - double a_minus_p_dot_n = a_minus_p.Dot( n ); - TVector3 scaled_n = a_minus_p_dot_n * n; - //hit_to_wire_vector = a_minus_p - scaled_n; - return (a_minus_p - scaled_n); -} - -/////////////////////////////////////////////////////////////////////////////////////// -/////////////////////// CalculateNClusters //////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////// -std::pair DCHdigi::CalculateClusters(const edm4hep::SimTrackerHit & input_sim_hit) const -{ - std::pair return_values = {0,0}; - uint32_t & Ncl = return_values.first; - uint32_t & ClSz = return_values.second; - //_________________SET NECESSARY PARAMETERS FOR THE CLS ALGORITHM-----WALAA_________________// - - auto thisParticle = input_sim_hit.getParticle(); - // Parameters needed for the CL Algo //Added by Walaa/////// - ///from Createclusters.cpp//// - // int fNClusters; - double me = 0.511; - // float rnd; - float Eloss= 0.0; - // float DeltaE_per_track= 0.0; - // float EtotCell= 0.0; - int NCl; - int NCl1,NClp; - // float ClSz,ClSzP; - // float Rt=0.87; - float EIzp=15.8; - float ExECl1; - float ExECl; - float cut= 1000;//controlla - // float prc=0.83; - float EIzs=25.6; - // float ratio=prc/EIzs; - // int NCltot=0; - // float Edep=0.0; - // float DeltaE=0.0; - // int count; - // bool loop; - // float prvDiff; - // float tmpDiff[10]; - // float vecExECl[10]; - // float mintmpDiff; - // int iloop; - float ExECl1totRec; - // float SgmaxExECl; - // int Ncl; - float rndCorr; - float maxExECl=0.0; - // float ExSgm=0.0; - float totExECl; -// int ParentID; - const int nhEp=10;//10 - float hEpcut[10]={100,200,300,400,500,600,700,800,900,1000}; - int minE=1000; - int maxE=10000; - int binE=1000; - int nhE=(maxE-minE)/binE; - TString parClass; - // int Ncltot=0; - int NEltot=0; - // float Etot=0.0; - float maxEx0len,ExSgmlen; - int choice= 2; - // int Nev=500000; - // int val; - // float EtCut=0.7; - ///////end from Createclusters.cpp//// - -///////from Createclusters.h///////// - // TF1Convolution **cnvl =new TF1Convolution*[100];//100 for 1 cm gas box //Added by Walaa - // TF1 **fcnvl=new TF1 *[100]; //Added by Walaa - // float fnorm[100]; //Added by Walaa - double vecpar[5]; //Added by Walaa - std::vector vecEtr,vecEtrTot; - float sumVecTot,meanVecTot,sumVec,meanVec; -/////////end from Createclusters.h///////// - - // get rid of spurious compiler error, Werror=unused-but-set-variable - (void)NCl; - (void)vecpar; - (void)sumVecTot; - - int NCld; - TString parName; - double bg, Momentum, mass=-1e300; - std::vector vecExtraD; - - double Ffrac, Fmpv1, Fsgm1, Fmpv2, Fsgm2; - std::vector CorrpMean,CorrpSgm,Corrdgmean,Corrdgsgm,Corrdglfrac,Corrdglmpvl,Corrdglsgml,Corrdglmeang,Corrdglsgmg; - float Ekdelta; - float maxEx0, maxExSlp, ExSgmlep, ExSgmhad; - float MPVEx, SgmEx, MeanEx1, SgmEx1, frac, Slp, CorrSlp, CorrInt; - double LengthTrack, Etot_per_track; - //////end parameters - bool IsSecondaryWithinDCH = false; - { - auto vertex = thisParticle.getVertex(); // in mm - auto vertexRsquared = vertex[0]*vertex[0] + vertex[1]*vertex[1]; - auto vertexZabs = std::fabs(vertex[2]); - float DCH_halflengh = 2000; - float DCH_rin_squared = 350*350; - float DCH_rout_squared = 2000*2000; - IsSecondaryWithinDCH = (vertexZabs < DCH_halflengh) && (vertexRsquared>DCH_rin_squared) && (vertexRsquaredget_Ffrac(bg);//0.9; - Fmpv1=flData->get_Fmpv1(bg);//43; - Fsgm1=flData->get_Fsgm1(bg);//9.64; - Fmpv2=flData->get_Fmpv2(bg);//311.3; - Fsgm2=flData->get_Fsgm2(bg);//35; - CorrpMean=flData->get_ClSzCorrpmean(bg); - CorrpSgm=flData->get_ClSzCorrpsgm(bg); - Corrdgmean=flData->get_ClSzCorrdgmean(bg); - Corrdgsgm=flData->get_ClSzCorrdgsgm(bg); - Corrdglfrac=flData->get_ClSzCorrdglfrac(bg); - Corrdglmpvl=flData->get_ClSzCorrdglmpvl(bg); - Corrdglsgml=flData->get_ClSzCorrdglsgml(bg); - Corrdglmeang=flData->get_ClSzCorrdglmeang(bg); - Corrdglsgmg=flData->get_ClSzCorrdglsgmg(bg); - maxEx0=flData->get_maxEx0(bg);//379.4 electron 100 gev - maxExSlp=flData->get_maxExSlp(); - // lepton PDG id goes from 11 to 16 (antiparticles have negative id) - bool IsLepton = (11 <= abs(pdgid) ) && (16 >= abs(pdgid) ); - if( IsLepton ){ - ExSgmlep=flData->get_ExSgmlep(); - }else{ - ExSgmhad=flData->get_ExSgmhad(); - } - - MPVEx=flData->get_MPVExtra(bg);//103.2 - SgmEx=flData->get_SgmExtra(bg);//28.5;// - MeanEx1=flData->get_MeanExtra1(bg);//13.8;// - SgmEx1=flData->get_SgmExtra1(bg);//9.72;// - frac=flData->get_FracExtra1(bg);//0.13;// - Slp=flData->get_SlopeExtra1(bg);//7.95;// - debug() << " maxEx0 "<< maxEx0<< " ExSgmhad "<get_ClSzCorrSlp(bg); - CorrInt=flData->get_ClSzCorrInt(bg); - - vecpar[0]=Ffrac; - vecpar[1]=Fmpv1; - vecpar[2]=Fsgm1; - vecpar[3]=Fmpv2; - vecpar[4]=Fsgm2; - - double Tmax = (2.0*me*pow(bg,2)/(1+(2.0*(1+pow(bg,2))*me/mass)+pow(me/mass,2)))*1e+6; - float maxEcut=cut; - if(TmaxSetRange(0,maxEcut); - * fcnvl[0]->SetParameters(vecpar[0],vecpar[1],vecpar[2],vecpar[3],vecpar[4]); - * cnvl[0]=nullptr;*/ - - - TF1 *land= new TF1("land","landaun"); - land->SetParameter(0,1); - land->SetParameter(1,MPVEx); - land->SetParameter(2,SgmEx); - land->SetRange(0,maxEcut); - - TF1 *exGauss=new TF1("exGauss","[0]*([1]*TMath::Gaus(x,[2],[3],true)+(1.0-[1])*TMath::Exp(-x/[4])/[4])"); - exGauss->SetParameter(0,1); - exGauss->SetParameter(1,frac); - exGauss->SetParameter(2,MeanEx1); - exGauss->SetParameter(3,SgmEx1); - exGauss->SetParameter(4,Slp); - exGauss->SetRange(0,90); - - - // int MaxEv = Entries > Nev ? Nev : Entries; - // cout<<" MAXEV"<myRandom.Gaus(0,ExSgmlen))/maxExSlp; - // cout<<"maxExECl= "<(EIzp+EIzs)&&maxExECl>totExECl && while1counter<1e6){ - while1counter++; - // cout<<"start again"<Eloss) ExECl=Eloss; - totExECl+=ExECl; - // cout<<"totExECl= " <myRandom.Uniform(0,1); - if(rndCorrmyRandom.Gaus(Corrdglmeang[tmphE],Corrdglsgmg[tmphE]); - }else{ - tmpCl=this->myRandom.Landau(Corrdglmpvl[tmphE],Corrdglsgml[tmphE]); - } - }else{ - tmpCl=this->myRandom.Gaus(Corrdgmean[tmphE],Corrdgsgm[tmphE]); - } - - ClSz=TMath::Nint(vecExtraD[i]*CorrSlp+CorrInt-tmpCl); - if(ClSz<2) {ClSz=2;} - // TODO Alvaro: check what is ClSz??? - // output_digi_hit.setClusterSize(ClSz); - // hClSzRec->Fill(ClSz); - // hClSzDRec->Fill(ClSz); - // fClusterCharge.push_back(ClSz); - NEltot+=ClSz; - - } - - Ncl=NCl1+NClp+NCld; - debug() <<"Ncl= "<< Ncl<<" NCl1= "<size() << endmsg; - - // output_digi_hit.setClusterCount(Ncl); - - /* for (int icl=0;icl Date: Tue, 15 Oct 2024 12:39:26 +0200 Subject: [PATCH 35/56] indentation corrected --- DCHdigi/src/DCHdigi.cpp | 658 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 658 insertions(+) diff --git a/DCHdigi/src/DCHdigi.cpp b/DCHdigi/src/DCHdigi.cpp index e69de29..af89608 100644 --- a/DCHdigi/src/DCHdigi.cpp +++ b/DCHdigi/src/DCHdigi.cpp @@ -0,0 +1,658 @@ +#include "DCHdigi.h" + +// STL +#include +#include + +#include "extension/MutableDriftChamberDigiV2.h" + +/////////////////////////////////////////////////////////////////////////////////////// +/////////////////////// DCHdigi constructor //////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////// +// -- KeyValues("name of the variable that holds the name of the collection exposed in the python steering file", {"default name for the collection"}), +DCHdigi::DCHdigi(const std::string& name, ISvcLocator* svcLoc) + : MultiTransformer(name, svcLoc, + { + KeyValues("DCH_simhits", {""}), + KeyValues("HeaderName", {"EventHeader"}), + }, + {KeyValues("DCH_DigiCollection", {"DCH_DigiCollection"}), + KeyValues("DCH_DigiSimAssociationCollection", {"DCH_DigiSimAssociationCollection"})}) { + m_geoSvc = serviceLocator()->service(m_geoSvcName); + m_uidSvc = serviceLocator()->service(m_uidSvcName); +} + +/////////////////////////////////////////////////////////////////////////////////////// +/////////////////////// initialize //////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////// +StatusCode DCHdigi::initialize() { + if (!m_uidSvc) + ThrowException("Unable to get UniqueIDGenSvc"); + + m_gauss_z_cm = std::normal_distribution(0., m_z_resolution.value() * MM_TO_CM); + m_gauss_xy_cm = std::normal_distribution(0., m_xy_resolution.value() * MM_TO_CM); + + //----------------- + // Retrieve the subdetector + std::string DCH_name(m_DCH_name.value()); + if (0 == m_geoSvc->getDetector()->detectors().count(DCH_name)) { + ThrowException("Detector <<" + DCH_name + ">> does not exist."); + } + + dd4hep::DetElement DCH_DE = m_geoSvc->getDetector()->detectors().at(DCH_name); + + /////////////////////////////////////////////////////////////////////////////////// + /////////////////////////// retrieve data extension ////////////////////////// + /////////////////////////////////////////////////////////////////////////////////// + this->dch_data = DCH_DE.extension(); + + /////////////////////////////////////////////////////////////////////////////////// + + //----------------- + // Retrieve the readout associated with the detector element (subdetector) + dd4hep::SensitiveDetector dch_sd = m_geoSvc->getDetector()->sensitiveDetector(DCH_name); + if (not dch_sd.isValid()) + ThrowException("No valid Sensitive Detector was found for detector <<" + DCH_name + ">>."); + + dd4hep::Readout dch_readout = dch_sd.readout(); + // set the cellID decoder + m_decoder = dch_readout.idSpec().decoder(); + + /////////////////////////////////////////////////////////////////////////////////// + ////////////////// initialize Walaa's code for Cluster counting ///////////////// + /////////////////////////////////////////////////////////////////////////////////// + debug() << Form("Opening %s...", m_fileDataAlg.value().c_str()) << endmsg; + if (not IsFileGood(m_fileDataAlg.value())) + ThrowException("File <<" + m_fileDataAlg.value() + ">> not found."); + flData = new AlgData(); + flData->Load_file(m_fileDataAlg.value().c_str()); + flData->Load_interp(); + debug() << Form("Opening %s... Done", m_fileDataAlg.value().c_str()) << endmsg; + /////////////////////////////////////////////////////////////////////////////////// + + std::stringstream ss; + PrintConfiguration(ss); + info() << ss.str().c_str() << endmsg; + if (m_create_debug_histos.value()) { + hDpw = new TH1D("hDpw", "Distance hit to the wire, in cm", 100, 0, 1); + hDpw->SetDirectory(0); + hDww = new TH1D("hDww", "Distance hit projection to the wire, in cm. Should be zero", 100, 0, 1); + hDww->SetDirectory(0); + hSz = new TH1D("hSz", "Smearing along the wire, in cm", 100, 0, 5 * m_z_resolution.value()); + hSz->SetDirectory(0); + hSxy = new TH1D("hSxy", "Smearing perpendicular the wire, in cm", 100, 0, 5 * m_xy_resolution.value()); + hSxy->SetDirectory(0); + } + return StatusCode::SUCCESS; +} + +/////////////////////////////////////////////////////////////////////////////////////// +/////////////////////// operator() //////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////// +std::tuple +DCHdigi::operator()(const edm4hep::SimTrackerHitCollection& input_sim_hits, + const edm4hep::EventHeaderCollection& headers) const { + // initialize seed for random engine + this->PrepareRandomEngine(headers); + + debug() << "Input Sim Hit collection size: " << input_sim_hits.size() << endmsg; + + // Create the collections we are going to return + extension::DriftChamberDigiV2Collection output_digi_hits; + extension::MCRecoDriftChamberDigiV2AssociationCollection output_digi_sim_association; + + //loop over hit collection + for (const auto& input_sim_hit : input_sim_hits) { + dd4hep::DDSegmentation::CellID cellid = input_sim_hit.getCellID(); + int ilayer = this->CalculateLayerFromCellID(cellid); + int nphi = this->CalculateNphiFromCellID(cellid); + auto hit_position = Convert_EDM4hepVector_to_TVector3(input_sim_hit.getPosition(), MM_TO_CM); + + // ------------------------------------------------------------------------- + // calculate hit position projection into the wire + TVector3 hit_to_wire_vector = this->Calculate_hitpos_to_wire_vector(ilayer, nphi, hit_position); + TVector3 hit_projection_on_the_wire = hit_position + hit_to_wire_vector; + if (m_create_debug_histos.value()) { + double distance_hit_wire = hit_to_wire_vector.Mag(); + hDpw->Fill(distance_hit_wire); + } + TVector3 wire_direction_ez = this->Calculate_wire_vector_ez(ilayer, nphi); + + // ------------------------------------------------------------------------- + // smear the position + + // smear position along the wire + double smearing_z = m_gauss_z_cm(m_engine); + if (m_create_debug_histos.value()) + hSz->Fill(smearing_z); + + hit_projection_on_the_wire += smearing_z * (wire_direction_ez.Unit()); + if (m_create_debug_histos.value()) { + // the distance from the hit projection and the wire should be zero + TVector3 dummy_vector = this->Calculate_hitpos_to_wire_vector(ilayer, nphi, hit_projection_on_the_wire); + hDww->Fill(dummy_vector.Mag()); + } + + // smear position perpendicular to the wire + double smearing_xy = m_gauss_xy_cm(m_engine); + if (m_create_debug_histos.value()) + hSxy->Fill(smearing_xy); + float distanceToWire_real = hit_to_wire_vector.Mag(); + + // protect against negative values + float distanceToWire_smeared = std::max(0.0, distanceToWire_real + smearing_xy); + + std::int32_t type = 0; + std::int32_t quality = 0; + float eDepError = 0; + // length units back to mm + auto positionSW = Convert_TVector3_to_EDM4hepVector(hit_projection_on_the_wire, 1. / MM_TO_CM); + auto directionSW = Convert_TVector3_to_EDM4hepVector(wire_direction_ez, 1. / MM_TO_CM); + float distanceToWire = distanceToWire_smeared / MM_TO_CM; + + auto [nCluster, nElectronPerCluster] = CalculateClusters(input_sim_hit); + + extension::MutableDriftChamberDigiV2 oDCHdigihit; + oDCHdigihit.setCellID(input_sim_hit.getCellID()); + oDCHdigihit.setType(type); + oDCHdigihit.setQuality(quality); + oDCHdigihit.setTime(input_sim_hit.getTime()); + oDCHdigihit.setEDep(input_sim_hit.getEDep()); + oDCHdigihit.setEDepError(eDepError); + oDCHdigihit.setPosition(positionSW); + oDCHdigihit.setDirectionSW(directionSW); + oDCHdigihit.setDistanceToWire(distanceToWire); + oDCHdigihit.setNCluster(nCluster); + oDCHdigihit.setNElectronPerCluster(nElectronPerCluster); + + output_digi_hits.push_back(oDCHdigihit); + + extension::MutableMCRecoDriftChamberDigiV2Association oDCHsimdigi_association; + oDCHsimdigi_association.setDigi(oDCHdigihit); + oDCHsimdigi_association.setSim(input_sim_hit); + output_digi_sim_association.push_back(oDCHsimdigi_association); + + } // end loop over hit collection + + ///////////////////////////////////////////////////////////////// + return std::make_tuple( + std::move(output_digi_hits), std::move(output_digi_sim_association)); +} + +/////////////////////////////////////////////////////////////////////////////////////// +/////////////////////// finalize ////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////// +StatusCode DCHdigi::finalize() { + if (m_create_debug_histos.value()) { + std::unique_ptr ofile{TFile::Open(m_out_debug_filename.value().c_str(), "recreate")}; + ofile->cd(); + hDpw->Write(); + hDww->Write(); + hSxy->Write(); + hSz->Write(); + } + + return StatusCode::SUCCESS; +} + +/////////////////////////////////////////////////////////////////////////////////////// +/////////////////////// ThrowException //////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////// +void DCHdigi::ThrowException(std::string s) const { + error() << s.c_str() << endmsg; + throw std::runtime_error(s); +} + +/////////////////////////////////////////////////////////////////////////////////////// +/////////////////////// PrintConfiguration //////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////// +void DCHdigi::PrintConfiguration(std::ostream& io) { + io << "DCHdigi will use the following components:\n"; + io << "\tGeometry Service: " << m_geoSvcName.value().c_str() << "\n"; + io << "\tUID Service: " << m_uidSvcName.value().c_str() << "\n"; + io << "\tDetector name: " << m_DCH_name.value().c_str() << "\n"; + io << "\t\t|--Volume bitfield: " << m_decoder->fieldDescription().c_str() << "\n"; + io << "\t\t|--Number of layers: " << dch_data->database.size() << "\n"; + io << "\tCluster distributions taken from: " << m_fileDataAlg.value().c_str() << "\n"; + io << "\tResolution along the wire (mm): " << m_z_resolution.value() << "\n"; + io << "\tResolution perp. to the wire (mm): " << m_xy_resolution.value() << "\n"; + return; +} + +void DCHdigi::PrepareRandomEngine(const edm4hep::EventHeaderCollection& headers) const { + uint32_t evt_n = headers[0].getEventNumber(); + uint32_t run_n = headers[0].getRunNumber(); + size_t seed = m_uidSvc->getUniqueID(evt_n, run_n, this->name()); + m_engine.seed(seed); + // advance internal state to minimize possibility of creating correlations + m_engine.discard(10); + for (int i = 0; i < 10; ++i) + myRandom.Rndm(); +} + +/////////////////////////////////////////////////////////////////////////////////////// +///// Ancillary functions for calculating the distance to the wire //////// +/////////////////////////////////////////////////////////////////////////////////////// + +TVector3 DCHdigi::Calculate_wire_vector_ez(int ilayer, int nphi) const { + auto& l = this->dch_data->database.at(ilayer); + + // See original paper Hoshina et al, Computer Physics Communications 153 (2003) 3 + // eq. 2.9, for the definition of ez, vector along the wire + + // initialize some variables + int stereosign = l.StereoSign(); + double rz0 = l.radius_sw_z0; + double dphi = dch_data->twist_angle; + // kappa is the same as in eq. 2.9 + double kappa = (1. / dch_data->Lhalf) * tan(dphi / 2); + + //--- calculating wire position + // the points p1 and p2 correspond to the ends of the wire + + // point 1 + // double x1 = rz0; // m + // double y1 = 0.; // m + // double z1 = 0.; // m + double x1 = rz0; // m + double y1 = -stereosign * rz0 * kappa * dch_data->Lhalf; // m + double z1 = -dch_data->Lhalf; // m + + TVector3 p1(x1, y1, z1); + + // point 2 + double x2 = rz0; // m + double y2 = stereosign * rz0 * kappa * dch_data->Lhalf; // m + double z2 = dch_data->Lhalf; // m + + TVector3 p2(x2, y2, z2); + + // calculate phi rotation of whole twisted tube, ie, rotation at z=0 + double phi_z0 = Calculate_wire_phi_z0(ilayer, nphi); + p1.RotateZ(phi_z0); + p2.RotateZ(phi_z0); + + //--- end calculating wire position + + return (p2 - p1).Unit(); +} + +TVector3 DCHdigi::Calculate_wire_z0_point(int ilayer, int nphi) const { + auto& l = this->dch_data->database.at(ilayer); + double rz0 = l.radius_sw_z0; + TVector3 p1(rz0, 0, 0); + double phi_z0 = Calculate_wire_phi_z0(ilayer, nphi); + p1.RotateZ(phi_z0); + return p1; +} + +// calculate phi rotation of whole twisted tube, ie, rotation at z=0 +double DCHdigi::Calculate_wire_phi_z0(int ilayer, int nphi) const { + auto& l = this->dch_data->database.at(ilayer); + int ncells = l.nwires / 2; + double phistep = TMath::TwoPi() / ncells; + double phi_z0 = (nphi + 0.25 * (l.layer % 2)) * phistep; + return phi_z0; +} + +/////////////////////////////////////////////////////////////////////////////////////// +/////////////////////// Calculate vector from hit position to wire ///////////////// +/////////////////////////////////////////////////////////////////////////////////////// +TVector3 DCHdigi::Calculate_hitpos_to_wire_vector(int ilayer, int nphi, const TVector3& hit_position /*in cm*/) const { + // Solution distance from a point to a line given here: + // https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line#Vector_formulation + TVector3 n = this->Calculate_wire_vector_ez(ilayer, nphi); + TVector3 a = this->Calculate_wire_z0_point(ilayer, nphi); + // Remember using cm as natural units of DD4hep consistently! + // TVector3 p {hit_position.x()*MM_TO_CM,hit_position.y()*MM_TO_CM,hit_position.z()*MM_TO_CM}; + + TVector3 a_minus_p = a - hit_position; + double a_minus_p_dot_n = a_minus_p.Dot(n); + TVector3 scaled_n = a_minus_p_dot_n * n; + //hit_to_wire_vector = a_minus_p - scaled_n; + return (a_minus_p - scaled_n); +} + +/////////////////////////////////////////////////////////////////////////////////////// +/////////////////////// CalculateNClusters //////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////// +std::pair DCHdigi::CalculateClusters(const edm4hep::SimTrackerHit& input_sim_hit) const { + std::pair return_values = {0, 0}; + uint32_t& Ncl = return_values.first; + uint32_t& ClSz = return_values.second; + //_________________SET NECESSARY PARAMETERS FOR THE CLS ALGORITHM-----WALAA_________________// + + auto thisParticle = input_sim_hit.getParticle(); + // Parameters needed for the CL Algo //Added by Walaa/////// + ///from Createclusters.cpp//// + // int fNClusters; + double me = 0.511; + // float rnd; + float Eloss = 0.0; + // float DeltaE_per_track= 0.0; + // float EtotCell= 0.0; + int NCl; + int NCl1, NClp; + // float ClSz,ClSzP; + // float Rt=0.87; + float EIzp = 15.8; + float ExECl1; + float ExECl; + float cut = 1000; //controlla + // float prc=0.83; + float EIzs = 25.6; + // float ratio=prc/EIzs; + // int NCltot=0; + // float Edep=0.0; + // float DeltaE=0.0; + // int count; + // bool loop; + // float prvDiff; + // float tmpDiff[10]; + // float vecExECl[10]; + // float mintmpDiff; + // int iloop; + float ExECl1totRec; + // float SgmaxExECl; + // int Ncl; + float rndCorr; + float maxExECl = 0.0; + // float ExSgm=0.0; + float totExECl; + // int ParentID; + const int nhEp = 10; //10 + float hEpcut[10] = {100, 200, 300, 400, 500, 600, 700, 800, 900, 1000}; + int minE = 1000; + int maxE = 10000; + int binE = 1000; + int nhE = (maxE - minE) / binE; + TString parClass; + // int Ncltot=0; + int NEltot = 0; + // float Etot=0.0; + float maxEx0len, ExSgmlen; + int choice = 2; + // int Nev=500000; + // int val; + // float EtCut=0.7; + ///////end from Createclusters.cpp//// + + ///////from Createclusters.h///////// + // TF1Convolution **cnvl =new TF1Convolution*[100];//100 for 1 cm gas box //Added by Walaa + // TF1 **fcnvl=new TF1 *[100]; //Added by Walaa + // float fnorm[100]; //Added by Walaa + double vecpar[5]; //Added by Walaa + std::vector vecEtr, vecEtrTot; + float sumVecTot, meanVecTot, sumVec, meanVec; + /////////end from Createclusters.h///////// + + // get rid of spurious compiler error, Werror=unused-but-set-variable + (void)NCl; + (void)vecpar; + (void)sumVecTot; + + int NCld; + TString parName; + double bg, Momentum, mass = -1e300; + std::vector vecExtraD; + + double Ffrac, Fmpv1, Fsgm1, Fmpv2, Fsgm2; + std::vector CorrpMean, CorrpSgm, Corrdgmean, Corrdgsgm, Corrdglfrac, Corrdglmpvl, Corrdglsgml, Corrdglmeang, + Corrdglsgmg; + float Ekdelta; + float maxEx0, maxExSlp, ExSgmlep, ExSgmhad; + float MPVEx, SgmEx, MeanEx1, SgmEx1, frac, Slp, CorrSlp, CorrInt; + double LengthTrack, Etot_per_track; + //////end parameters + bool IsSecondaryWithinDCH = false; + { + auto vertex = thisParticle.getVertex(); // in mm + auto vertexRsquared = vertex[0] * vertex[0] + vertex[1] * vertex[1]; + auto vertexZabs = std::fabs(vertex[2]); + float DCH_halflengh = 2000; + float DCH_rin_squared = 350 * 350; + float DCH_rout_squared = 2000 * 2000; + IsSecondaryWithinDCH = + (vertexZabs < DCH_halflengh) && (vertexRsquared > DCH_rin_squared) && (vertexRsquared < DCH_rout_squared); + } + Momentum = sqrt((input_sim_hit.getMomentum().x * input_sim_hit.getMomentum().x) + + (input_sim_hit.getMomentum().y * input_sim_hit.getMomentum().y) + + (input_sim_hit.getMomentum().z * input_sim_hit.getMomentum().z)); + + NCld = 0; + int pdgid = thisParticle.getPDG(); + if (IsSecondaryWithinDCH && 11 == pdgid) { + NCld++; + Ekdelta = (TMath::Sqrt(Momentum * Momentum + me * me) - me) * 1e6; + vecExtraD.push_back(Ekdelta); + } + debug() << "NCld= " << NCld << "vecExtraD= " << vecExtraD << endmsg; + if (NCld > 0) + debug() << "There is delta rays" << endmsg; + + mass = (thisParticle.getMass() / 1000.); // mass in GeV, required in MeV + bg = Momentum / mass; + + Ffrac = flData->get_Ffrac(bg); //0.9; + Fmpv1 = flData->get_Fmpv1(bg); //43; + Fsgm1 = flData->get_Fsgm1(bg); //9.64; + Fmpv2 = flData->get_Fmpv2(bg); //311.3; + Fsgm2 = flData->get_Fsgm2(bg); //35; + CorrpMean = flData->get_ClSzCorrpmean(bg); + CorrpSgm = flData->get_ClSzCorrpsgm(bg); + Corrdgmean = flData->get_ClSzCorrdgmean(bg); + Corrdgsgm = flData->get_ClSzCorrdgsgm(bg); + Corrdglfrac = flData->get_ClSzCorrdglfrac(bg); + Corrdglmpvl = flData->get_ClSzCorrdglmpvl(bg); + Corrdglsgml = flData->get_ClSzCorrdglsgml(bg); + Corrdglmeang = flData->get_ClSzCorrdglmeang(bg); + Corrdglsgmg = flData->get_ClSzCorrdglsgmg(bg); + maxEx0 = flData->get_maxEx0(bg); //379.4 electron 100 gev + maxExSlp = flData->get_maxExSlp(); + // lepton PDG id goes from 11 to 16 (antiparticles have negative id) + bool IsLepton = (11 <= abs(pdgid)) && (16 >= abs(pdgid)); + if (IsLepton) { + ExSgmlep = flData->get_ExSgmlep(); + } else { + ExSgmhad = flData->get_ExSgmhad(); + } + + MPVEx = flData->get_MPVExtra(bg); //103.2 + SgmEx = flData->get_SgmExtra(bg); //28.5;// + MeanEx1 = flData->get_MeanExtra1(bg); //13.8;// + SgmEx1 = flData->get_SgmExtra1(bg); //9.72;// + frac = flData->get_FracExtra1(bg); //0.13;// + Slp = flData->get_SlopeExtra1(bg); //7.95;// + debug() << " maxEx0 " << maxEx0 << " ExSgmhad " << ExSgmhad << " MPVEx " << MPVEx << " SgmEx " << SgmEx << endmsg; + CorrSlp = flData->get_ClSzCorrSlp(bg); + CorrInt = flData->get_ClSzCorrInt(bg); + + vecpar[0] = Ffrac; + vecpar[1] = Fmpv1; + vecpar[2] = Fsgm1; + vecpar[3] = Fmpv2; + vecpar[4] = Fsgm2; + + double Tmax = (2.0 * me * pow(bg, 2) / (1 + (2.0 * (1 + pow(bg, 2)) * me / mass) + pow(me / mass, 2))) * 1e+6; + float maxEcut = cut; + if (Tmax < maxEcut) { + maxEcut = Tmax; + } + //cout << "Tmax ="<SetRange(0,maxEcut); + * fcnvl[0]->SetParameters(vecpar[0],vecpar[1],vecpar[2],vecpar[3],vecpar[4]); + * cnvl[0]=nullptr;*/ + + TF1* land = new TF1("land", "landaun"); + land->SetParameter(0, 1); + land->SetParameter(1, MPVEx); + land->SetParameter(2, SgmEx); + land->SetRange(0, maxEcut); + + TF1* exGauss = new TF1("exGauss", "[0]*([1]*TMath::Gaus(x,[2],[3],true)+(1.0-[1])*TMath::Exp(-x/[4])/[4])"); + exGauss->SetParameter(0, 1); + exGauss->SetParameter(1, frac); + exGauss->SetParameter(2, MeanEx1); + exGauss->SetParameter(3, SgmEx1); + exGauss->SetParameter(4, Slp); + exGauss->SetRange(0, 90); + + // int MaxEv = Entries > Nev ? Nev : Entries; + // cout<<" MAXEV"<myRandom.Gaus(0, ExSgmlen)) / maxExSlp; + // cout<<"maxExECl= "< (EIzp + EIzs) && maxExECl > totExECl && while1counter < 1e6) { + while1counter++; + // cout<<"start again"< Eloss) + ExECl = Eloss; + totExECl += ExECl; + // cout<<"totExECl= " <myRandom.Uniform(0, 1); + if (rndCorr < Corrdglfrac[tmphE]) { + tmpCl = this->myRandom.Gaus(Corrdglmeang[tmphE], Corrdglsgmg[tmphE]); + } else { + tmpCl = this->myRandom.Landau(Corrdglmpvl[tmphE], Corrdglsgml[tmphE]); + } + } else { + tmpCl = this->myRandom.Gaus(Corrdgmean[tmphE], Corrdgsgm[tmphE]); + } + + ClSz = TMath::Nint(vecExtraD[i] * CorrSlp + CorrInt - tmpCl); + if (ClSz < 2) { + ClSz = 2; + } + // TODO Alvaro: check what is ClSz??? + // output_digi_hit.setClusterSize(ClSz); + // hClSzRec->Fill(ClSz); + // hClSzDRec->Fill(ClSz); + // fClusterCharge.push_back(ClSz); + NEltot += ClSz; + } + + Ncl = NCl1 + NClp + NCld; + debug() << "Ncl= " << Ncl << " NCl1= " << NCl1 << "NClp= " << NClp << "NCld= " << NCld << endmsg; + debug() << "NCld= " << NCld << " vecExtraD.size() " << vecExtraD.size() << endmsg; + int vecExtraD_size = vecExtraD.size(); + if (NCld != vecExtraD_size) + debug() << "There is a bug" << endmsg; + //debug() << "Output Digi Hit collection size: " << output_digi_hits->size() << endmsg; + + // output_digi_hit.setClusterCount(Ncl); + + /* for (int icl=0;icl Date: Tue, 15 Oct 2024 12:43:47 +0200 Subject: [PATCH 36/56] avoid downloading several times the cluster input file --- DCHdigi/test/test_DCHdigi/test_DCHdigi.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/DCHdigi/test/test_DCHdigi/test_DCHdigi.sh b/DCHdigi/test/test_DCHdigi/test_DCHdigi.sh index 6163b6e..4980638 100644 --- a/DCHdigi/test/test_DCHdigi/test_DCHdigi.sh +++ b/DCHdigi/test/test_DCHdigi/test_DCHdigi.sh @@ -9,7 +9,8 @@ ddsim --steeringFile sim_steering.py --outputFile 'dch_proton_10GeV.root' -N 10 # download file for cluster counting technique ifilename="https://fccsw.web.cern.ch/fccsw/filesForSimDigiReco/IDEA/DataAlgFORGEANT.root" -wget $ifilename +# -nc, --no-clobber: skip downloads that would download to existing files +wget --no-clobber $ifilename # Check if the input file exists if [[ ! -f "$(basename $ifilename)" ]]; then From 30d782e1da0a4a7a7d38f976536f9c278470681f Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Tue, 15 Oct 2024 16:42:45 +0200 Subject: [PATCH 37/56] initialize variables, fix compilation in ubuntu --- DCHdigi/src/DCHdigi.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/DCHdigi/src/DCHdigi.cpp b/DCHdigi/src/DCHdigi.cpp index af89608..5933495 100644 --- a/DCHdigi/src/DCHdigi.cpp +++ b/DCHdigi/src/DCHdigi.cpp @@ -392,18 +392,18 @@ std::pair DCHdigi::CalculateClusters(const edm4hep::SimTrack (void)vecpar; (void)sumVecTot; - int NCld; + int NCld(0); TString parName; - double bg, Momentum, mass = -1e300; + double bg(0), Momentum(0), mass = -1e300; std::vector vecExtraD; double Ffrac, Fmpv1, Fsgm1, Fmpv2, Fsgm2; std::vector CorrpMean, CorrpSgm, Corrdgmean, Corrdgsgm, Corrdglfrac, Corrdglmpvl, Corrdglsgml, Corrdglmeang, Corrdglsgmg; - float Ekdelta; - float maxEx0, maxExSlp, ExSgmlep, ExSgmhad; - float MPVEx, SgmEx, MeanEx1, SgmEx1, frac, Slp, CorrSlp, CorrInt; - double LengthTrack, Etot_per_track; + float Ekdelta(0); + float maxEx0(0), maxExSlp(0), ExSgmlep(0), ExSgmhad(0); + float MPVEx(0), SgmEx(0), MeanEx1(0), SgmEx1(0), frac(0), Slp(0), CorrSlp(0), CorrInt(0); + double LengthTrack(0), Etot_per_track(0); //////end parameters bool IsSecondaryWithinDCH = false; { From 1aa738b758efc2eb6d7ba6ae6c5b339cb5cca864 Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Fri, 18 Oct 2024 17:06:55 +0200 Subject: [PATCH 38/56] major refactorization of cluster counting function --- DCHdigi/include/DCHdigi.h | 2 + DCHdigi/src/DCHdigi.cpp | 520 ++++++++++++++++---------------------- 2 files changed, 213 insertions(+), 309 deletions(-) diff --git a/DCHdigi/include/DCHdigi.h b/DCHdigi/include/DCHdigi.h index 7ac53a3..2ea9695 100644 --- a/DCHdigi/include/DCHdigi.h +++ b/DCHdigi/include/DCHdigi.h @@ -175,6 +175,8 @@ struct DCHdigi final /// code developed by Walaa for calculating number of clusters and cluster size std::pair CalculateClusters(const edm4hep::SimTrackerHit& input_sim_hit) const; + bool IsParticleCreatedInsideDriftChamber(const edm4hep::MCParticle &) const ; + //------------------------------------------------------------------ // debug information diff --git a/DCHdigi/src/DCHdigi.cpp b/DCHdigi/src/DCHdigi.cpp index 5933495..2fee9b6 100644 --- a/DCHdigi/src/DCHdigi.cpp +++ b/DCHdigi/src/DCHdigi.cpp @@ -317,342 +317,244 @@ TVector3 DCHdigi::Calculate_hitpos_to_wire_vector(int ilayer, int nphi, const TV /////////////////////////////////////////////////////////////////////////////////////// /////////////////////// CalculateNClusters //////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// + +bool DCHdigi::IsParticleCreatedInsideDriftChamber(const edm4hep::MCParticle & thisParticle) const +{ + auto vertex = thisParticle.getVertex(); // in mm + auto vertexRsquared = vertex[0] * vertex[0] + vertex[1] * vertex[1]; + auto vertexZabs = std::fabs(vertex[2]); + float DCH_halflengh = dch_data->Lhalf / dd4hep::mm; //2000; + float DCH_rin_squared = std::pow(dch_data->rin / dd4hep::mm,2); //350 * 350; + float DCH_rout_squared = std::pow(dch_data->rout / dd4hep::mm,2); //2000 * 2000; + return (vertexZabs < DCH_halflengh) && (vertexRsquared > DCH_rin_squared) && (vertexRsquared < DCH_rout_squared); +} + std::pair DCHdigi::CalculateClusters(const edm4hep::SimTrackerHit& input_sim_hit) const { - std::pair return_values = {0, 0}; - uint32_t& Ncl = return_values.first; - uint32_t& ClSz = return_values.second; + + /// vector to accumulate the size of each cluster + std::vector ClSz_vector; //_________________SET NECESSARY PARAMETERS FOR THE CLS ALGORITHM-----WALAA_________________// - auto thisParticle = input_sim_hit.getParticle(); // Parameters needed for the CL Algo //Added by Walaa/////// ///from Createclusters.cpp//// - // int fNClusters; - double me = 0.511; - // float rnd; float Eloss = 0.0; - // float DeltaE_per_track= 0.0; - // float EtotCell= 0.0; - int NCl; - int NCl1, NClp; - // float ClSz,ClSzP; - // float Rt=0.87; float EIzp = 15.8; - float ExECl1; - float ExECl; + float ExECl1 = 0; float cut = 1000; //controlla - // float prc=0.83; float EIzs = 25.6; - // float ratio=prc/EIzs; - // int NCltot=0; - // float Edep=0.0; - // float DeltaE=0.0; - // int count; - // bool loop; - // float prvDiff; - // float tmpDiff[10]; - // float vecExECl[10]; - // float mintmpDiff; - // int iloop; - float ExECl1totRec; - // float SgmaxExECl; - // int Ncl; - float rndCorr; - float maxExECl = 0.0; - // float ExSgm=0.0; - float totExECl; - // int ParentID; - const int nhEp = 10; //10 + float ExECl1totRec = 0; + float rndCorr(0); + const int nhEp = 10; float hEpcut[10] = {100, 200, 300, 400, 500, 600, 700, 800, 900, 1000}; int minE = 1000; int maxE = 10000; int binE = 1000; int nhE = (maxE - minE) / binE; - TString parClass; - // int Ncltot=0; - int NEltot = 0; - // float Etot=0.0; - float maxEx0len, ExSgmlen; - int choice = 2; - // int Nev=500000; - // int val; - // float EtCut=0.7; - ///////end from Createclusters.cpp//// - - ///////from Createclusters.h///////// - // TF1Convolution **cnvl =new TF1Convolution*[100];//100 for 1 cm gas box //Added by Walaa - // TF1 **fcnvl=new TF1 *[100]; //Added by Walaa - // float fnorm[100]; //Added by Walaa - double vecpar[5]; //Added by Walaa - std::vector vecEtr, vecEtrTot; - float sumVecTot, meanVecTot, sumVec, meanVec; - /////////end from Createclusters.h///////// - - // get rid of spurious compiler error, Werror=unused-but-set-variable - (void)NCl; - (void)vecpar; - (void)sumVecTot; - - int NCld(0); - TString parName; - double bg(0), Momentum(0), mass = -1e300; - std::vector vecExtraD; - - double Ffrac, Fmpv1, Fsgm1, Fmpv2, Fsgm2; - std::vector CorrpMean, CorrpSgm, Corrdgmean, Corrdgsgm, Corrdglfrac, Corrdglmpvl, Corrdglsgml, Corrdglmeang, - Corrdglsgmg; - float Ekdelta(0); + float maxEx0len(0), ExSgmlen(0); + std::vector CorrpMean; + std::vector CorrpSgm; + std::vector Corrdgmean; + std::vector Corrdgsgm; + std::vector Corrdglfrac; + std::vector Corrdglmpvl; + std::vector Corrdglsgml; + std::vector Corrdglmeang; + std::vector Corrdglsgmg; float maxEx0(0), maxExSlp(0), ExSgmlep(0), ExSgmhad(0); float MPVEx(0), SgmEx(0), MeanEx1(0), SgmEx1(0), frac(0), Slp(0), CorrSlp(0), CorrInt(0); - double LengthTrack(0), Etot_per_track(0); - //////end parameters - bool IsSecondaryWithinDCH = false; + + /*________________________________________________________________________________*/ + const edm4hep::MCParticle & thisParticle = input_sim_hit.getParticle(); + bool IsSecondaryWithinDCH = IsParticleCreatedInsideDriftChamber(thisParticle); + + // Momentum from EDM4hep, in GeV + double Momentum = sqrt((input_sim_hit.getMomentum().x * input_sim_hit.getMomentum().x) + + (input_sim_hit.getMomentum().y * input_sim_hit.getMomentum().y) + + (input_sim_hit.getMomentum().z * input_sim_hit.getMomentum().z)); + + int thisparticle_pdgid = thisParticle.getPDG(); + int electron_pdgid = 11; + constexpr double me = 0.511; // electron mass in MeV + constexpr double me_GeV = me*1e-3; // electron mass in GeV + + /// number of clusters, with size > 1 electron + int NClp(0); + + /// number of clusters, with size = 1 electron + int NCl1(0); + + // TODO Alvaro: gamma rays as secondary are ignored? + if( not IsSecondaryWithinDCH ) { - auto vertex = thisParticle.getVertex(); // in mm - auto vertexRsquared = vertex[0] * vertex[0] + vertex[1] * vertex[1]; - auto vertexZabs = std::fabs(vertex[2]); - float DCH_halflengh = 2000; - float DCH_rin_squared = 350 * 350; - float DCH_rout_squared = 2000 * 2000; - IsSecondaryWithinDCH = - (vertexZabs < DCH_halflengh) && (vertexRsquared > DCH_rin_squared) && (vertexRsquared < DCH_rout_squared); - } - Momentum = sqrt((input_sim_hit.getMomentum().x * input_sim_hit.getMomentum().x) + - (input_sim_hit.getMomentum().y * input_sim_hit.getMomentum().y) + - (input_sim_hit.getMomentum().z * input_sim_hit.getMomentum().z)); - - NCld = 0; - int pdgid = thisParticle.getPDG(); - if (IsSecondaryWithinDCH && 11 == pdgid) { - NCld++; - Ekdelta = (TMath::Sqrt(Momentum * Momentum + me * me) - me) * 1e6; - vecExtraD.push_back(Ekdelta); - } - debug() << "NCld= " << NCld << "vecExtraD= " << vecExtraD << endmsg; - if (NCld > 0) - debug() << "There is delta rays" << endmsg; - - mass = (thisParticle.getMass() / 1000.); // mass in GeV, required in MeV - bg = Momentum / mass; - - Ffrac = flData->get_Ffrac(bg); //0.9; - Fmpv1 = flData->get_Fmpv1(bg); //43; - Fsgm1 = flData->get_Fsgm1(bg); //9.64; - Fmpv2 = flData->get_Fmpv2(bg); //311.3; - Fsgm2 = flData->get_Fsgm2(bg); //35; - CorrpMean = flData->get_ClSzCorrpmean(bg); - CorrpSgm = flData->get_ClSzCorrpsgm(bg); - Corrdgmean = flData->get_ClSzCorrdgmean(bg); - Corrdgsgm = flData->get_ClSzCorrdgsgm(bg); - Corrdglfrac = flData->get_ClSzCorrdglfrac(bg); - Corrdglmpvl = flData->get_ClSzCorrdglmpvl(bg); - Corrdglsgml = flData->get_ClSzCorrdglsgml(bg); - Corrdglmeang = flData->get_ClSzCorrdglmeang(bg); - Corrdglsgmg = flData->get_ClSzCorrdglsgmg(bg); - maxEx0 = flData->get_maxEx0(bg); //379.4 electron 100 gev - maxExSlp = flData->get_maxExSlp(); - // lepton PDG id goes from 11 to 16 (antiparticles have negative id) - bool IsLepton = (11 <= abs(pdgid)) && (16 >= abs(pdgid)); - if (IsLepton) { - ExSgmlep = flData->get_ExSgmlep(); - } else { - ExSgmhad = flData->get_ExSgmhad(); - } + // lepton PDG id goes from 11 to 16 (antiparticles have negative id) + bool IsLepton = (11 <= abs(thisparticle_pdgid)) && (16 >= abs(thisparticle_pdgid)); + if (IsLepton) { + ExSgmlep = flData->get_ExSgmlep(); + } else { + // TODO Alvaro: gamma rays treated as hadrons, is that ok? + ExSgmhad = flData->get_ExSgmhad(); + } - MPVEx = flData->get_MPVExtra(bg); //103.2 - SgmEx = flData->get_SgmExtra(bg); //28.5;// - MeanEx1 = flData->get_MeanExtra1(bg); //13.8;// - SgmEx1 = flData->get_SgmExtra1(bg); //9.72;// - frac = flData->get_FracExtra1(bg); //0.13;// - Slp = flData->get_SlopeExtra1(bg); //7.95;// - debug() << " maxEx0 " << maxEx0 << " ExSgmhad " << ExSgmhad << " MPVEx " << MPVEx << " SgmEx " << SgmEx << endmsg; - CorrSlp = flData->get_ClSzCorrSlp(bg); - CorrInt = flData->get_ClSzCorrInt(bg); - - vecpar[0] = Ffrac; - vecpar[1] = Fmpv1; - vecpar[2] = Fsgm1; - vecpar[3] = Fmpv2; - vecpar[4] = Fsgm2; - - double Tmax = (2.0 * me * pow(bg, 2) / (1 + (2.0 * (1 + pow(bg, 2)) * me / mass) + pow(me / mass, 2))) * 1e+6; - float maxEcut = cut; - if (Tmax < maxEcut) { - maxEcut = Tmax; - } - //cout << "Tmax ="<SetRange(0,maxEcut); - * fcnvl[0]->SetParameters(vecpar[0],vecpar[1],vecpar[2],vecpar[3],vecpar[4]); - * cnvl[0]=nullptr;*/ - - TF1* land = new TF1("land", "landaun"); - land->SetParameter(0, 1); - land->SetParameter(1, MPVEx); - land->SetParameter(2, SgmEx); - land->SetRange(0, maxEcut); - - TF1* exGauss = new TF1("exGauss", "[0]*([1]*TMath::Gaus(x,[2],[3],true)+(1.0-[1])*TMath::Exp(-x/[4])/[4])"); - exGauss->SetParameter(0, 1); - exGauss->SetParameter(1, frac); - exGauss->SetParameter(2, MeanEx1); - exGauss->SetParameter(3, SgmEx1); - exGauss->SetParameter(4, Slp); - exGauss->SetRange(0, 90); - - // int MaxEv = Entries > Nev ? Nev : Entries; - // cout<<" MAXEV"<myRandom.Gaus(0, ExSgmlen)) / maxExSlp; - // cout<<"maxExECl= "< (EIzp + EIzs) && maxExECl > totExECl && while1counter < 1e6) { - while1counter++; - // cout<<"start again"< Eloss) - ExECl = Eloss; - totExECl += ExECl; - // cout<<"totExECl= " <SetParameter(0, 1); + land->SetParameter(1, MPVEx); + land->SetParameter(2, SgmEx); + land->SetRange(0, maxEcut); + + TF1* exGauss = new TF1("exGauss", "[0]*([1]*TMath::Gaus(x,[2],[3],true)+(1.0-[1])*TMath::Exp(-x/[4])/[4])"); + exGauss->SetParameter(0, 1); + exGauss->SetParameter(1, frac); + exGauss->SetParameter(2, MeanEx1); + exGauss->SetParameter(3, SgmEx1); + exGauss->SetParameter(4, Slp); + exGauss->SetRange(0, 90); + + float totExECl = 0.0; + float ExECl = 0.0; + double LengthTrack = input_sim_hit.getPathLength(); + double Etot_per_track = input_sim_hit.getEDep(); + LengthTrack *= 0.1; //from mm to cm + Eloss = Etot_per_track * 1.e09; //from GeV to eV + maxEx0len = maxEx0 * LengthTrack; //maxEx0 is a parameter + if (IsLepton) { + ExSgmlen = ExSgmlep * TMath::Sqrt(LengthTrack); + } else { + ExSgmlen = ExSgmhad * TMath::Sqrt(LengthTrack); + } + float maxExECl = (Eloss - maxEx0len + this->myRandom.Gaus(0, ExSgmlen)) / maxExSlp; + + if (maxExECl < EIzs) { + maxExECl = 0.0; + } //EIzs const = 25.6 + + debug() << "Eloss= " << Eloss << "EIzs= " << EIzs << "EIzp= " << EIzp << "maxExECl= " << maxExECl << "totExECl" + << totExECl << endmsg; + + // The following loop calculate number of clusters of size > 1, NClp + for (int while1counter = 0; Eloss > (EIzp + EIzs) && maxExECl > totExECl && while1counter < 1e6; while1counter++ ) { + + ExECl = land->GetRandom(0, maxEcut); + + if (ExECl > EIzs) { + Eloss -= EIzp; + if (ExECl > (maxExECl - totExECl)) { + ExECl = maxExECl - totExECl; } + if (ExECl > Eloss) + ExECl = Eloss; + totExECl += ExECl; + Eloss -= ExECl; + NClp++; + //CLSZ + float tmpCorr = 0.0; + for (int i = 0; i < nhEp; ++i) { + if (ExECl >= (i == 0 ? 0 : hEpcut[i - 1]) && ExECl < hEpcut[i]) { + tmpCorr = this->myRandom.Gaus(CorrpMean[i], CorrpSgm[i]); + } + } + int ClSz = TMath::Nint(ExECl * CorrSlp + CorrInt - tmpCorr); + if (ClSz < 2) { + ClSz = 2; + } + ClSz_vector.push_back(ClSz); } - ClSz = TMath::Nint(ExECl * CorrSlp + CorrInt - tmpCorr); - if (ClSz < 2) { - ClSz = 2; - } - // TODO Alvaro: check what is ClSz??? - // output_digi_hit.setClusterSize(ClSz); - // hClSzRec->Fill(ClSz); - // hClSzRecND->Fill(ClSz); - NEltot += ClSz; - // fClusterCharge.push_back(ClSz); - // cout<<"ClSz= "<<"fClusterCharge= "<myRandom.Uniform(0, 1); - if (rndCorr < Corrdglfrac[tmphE]) { - tmpCl = this->myRandom.Gaus(Corrdglmeang[tmphE], Corrdglsgmg[tmphE]); + } //-- end if particle is not secondary + + // if particle is a delta electron created inside the drift chamber + int NCld(0); + if (IsSecondaryWithinDCH && electron_pdgid == thisparticle_pdgid) { + // 1 delta ray cause 1 cluster NCld (d=delta) + NCld = 1; + // Ekdelta in keV + float Ekdelta = (TMath::Sqrt(Momentum * Momentum + me_GeV * me_GeV) - me_GeV) * 1e6; + + // TODO Alvaro: what is this for? + { + float tmpCl; + int tmphE = (Ekdelta - minE) / binE; + if (tmphE >= nhE) + tmphE = nhE - 1; + if (tmphE == nhE - 1) { + rndCorr = this->myRandom.Uniform(0, 1); + if (rndCorr < Corrdglfrac[tmphE]) { + tmpCl = this->myRandom.Gaus(Corrdglmeang[tmphE], Corrdglsgmg[tmphE]); + } else { + tmpCl = this->myRandom.Landau(Corrdglmpvl[tmphE], Corrdglsgml[tmphE]); + } } else { - tmpCl = this->myRandom.Landau(Corrdglmpvl[tmphE], Corrdglsgml[tmphE]); + tmpCl = this->myRandom.Gaus(Corrdgmean[tmphE], Corrdgsgm[tmphE]); } - } else { - tmpCl = this->myRandom.Gaus(Corrdgmean[tmphE], Corrdgsgm[tmphE]); - } - ClSz = TMath::Nint(vecExtraD[i] * CorrSlp + CorrInt - tmpCl); - if (ClSz < 2) { - ClSz = 2; + int ClSz = TMath::Nint(Ekdelta * CorrSlp + CorrInt - tmpCl); + // TODO Alvaro: should it be 1 instead? + if (ClSz < 2) + { + ClSz = 2; + } + ClSz_vector.push_back(ClSz); } - // TODO Alvaro: check what is ClSz??? - // output_digi_hit.setClusterSize(ClSz); - // hClSzRec->Fill(ClSz); - // hClSzDRec->Fill(ClSz); - // fClusterCharge.push_back(ClSz); - NEltot += ClSz; + } + // conclusion: if hit caused by delta electron, NCld = 1, number of electrons ClSz=2 + + // value to be returned, sum of number of clusters size=1, size>1, and clusters caused by delta rays + int total_number_of_clusters = NCl1 + NClp + NCld; + debug() << "Ncl= " << total_number_of_clusters << " NCl1= " << NCl1 << "NClp= " << NClp << "NCld= " << NCld << endmsg; + + // value to be returned, total number of electrons (cluster size) + int total_number_of_electrons_over_all_clusters = 0; + for( auto cluster_size : ClSz_vector) + total_number_of_electrons_over_all_clusters += cluster_size; - Ncl = NCl1 + NClp + NCld; - debug() << "Ncl= " << Ncl << " NCl1= " << NCl1 << "NClp= " << NClp << "NCld= " << NCld << endmsg; - debug() << "NCld= " << NCld << " vecExtraD.size() " << vecExtraD.size() << endmsg; - int vecExtraD_size = vecExtraD.size(); - if (NCld != vecExtraD_size) - debug() << "There is a bug" << endmsg; - //debug() << "Output Digi Hit collection size: " << output_digi_hits->size() << endmsg; - - // output_digi_hit.setClusterCount(Ncl); - - /* for (int icl=0;icl Date: Fri, 18 Oct 2024 17:16:05 +0200 Subject: [PATCH 39/56] data extension modified, field was total number of electrons summed over all clusters during that step --- DCHdigi/dataFormatExtension/driftChamberHit.yaml | 2 +- DCHdigi/src/DCHdigi.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/DCHdigi/dataFormatExtension/driftChamberHit.yaml b/DCHdigi/dataFormatExtension/driftChamberHit.yaml index 8644114..891045c 100644 --- a/DCHdigi/dataFormatExtension/driftChamberHit.yaml +++ b/DCHdigi/dataFormatExtension/driftChamberHit.yaml @@ -57,7 +57,7 @@ datatypes: - edm4hep::Vector3d directionSW // direction of SW - float distanceToWire // distance hit-wire [mm] - uint32_t nCluster // number of clusters associated to this hit - - uint32_t nElectronPerCluster // number of electrons per cluster + - uint32_t nElectronsTotal // number of electrons for all the nCluster extension::MCRecoDriftChamberDigiV2Association: Description: "Association between a DriftChamberDigi and the corresponding simulated hit" diff --git a/DCHdigi/src/DCHdigi.cpp b/DCHdigi/src/DCHdigi.cpp index 2fee9b6..3e0ae3a 100644 --- a/DCHdigi/src/DCHdigi.cpp +++ b/DCHdigi/src/DCHdigi.cpp @@ -150,7 +150,7 @@ DCHdigi::operator()(const edm4hep::SimTrackerHitCollection& input_sim_hits, auto directionSW = Convert_TVector3_to_EDM4hepVector(wire_direction_ez, 1. / MM_TO_CM); float distanceToWire = distanceToWire_smeared / MM_TO_CM; - auto [nCluster, nElectronPerCluster] = CalculateClusters(input_sim_hit); + auto [nCluster, nElectronsTotal] = CalculateClusters(input_sim_hit); extension::MutableDriftChamberDigiV2 oDCHdigihit; oDCHdigihit.setCellID(input_sim_hit.getCellID()); @@ -163,7 +163,7 @@ DCHdigi::operator()(const edm4hep::SimTrackerHitCollection& input_sim_hits, oDCHdigihit.setDirectionSW(directionSW); oDCHdigihit.setDistanceToWire(distanceToWire); oDCHdigihit.setNCluster(nCluster); - oDCHdigihit.setNElectronPerCluster(nElectronPerCluster); + oDCHdigihit.setNElectronsTotal(nElectronsTotal); output_digi_hits.push_back(oDCHdigihit); From c5d0388bc034eab96c6e340220496874aa61c927 Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Fri, 18 Oct 2024 17:17:10 +0200 Subject: [PATCH 40/56] clang format of source code --- DCHdigi/src/DCHdigi.cpp | 149 +++++++++++++++++++--------------------- 1 file changed, 72 insertions(+), 77 deletions(-) diff --git a/DCHdigi/src/DCHdigi.cpp b/DCHdigi/src/DCHdigi.cpp index 3e0ae3a..04c41fc 100644 --- a/DCHdigi/src/DCHdigi.cpp +++ b/DCHdigi/src/DCHdigi.cpp @@ -318,39 +318,37 @@ TVector3 DCHdigi::Calculate_hitpos_to_wire_vector(int ilayer, int nphi, const TV /////////////////////// CalculateNClusters //////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// -bool DCHdigi::IsParticleCreatedInsideDriftChamber(const edm4hep::MCParticle & thisParticle) const -{ - auto vertex = thisParticle.getVertex(); // in mm - auto vertexRsquared = vertex[0] * vertex[0] + vertex[1] * vertex[1]; - auto vertexZabs = std::fabs(vertex[2]); - float DCH_halflengh = dch_data->Lhalf / dd4hep::mm; //2000; - float DCH_rin_squared = std::pow(dch_data->rin / dd4hep::mm,2); //350 * 350; - float DCH_rout_squared = std::pow(dch_data->rout / dd4hep::mm,2); //2000 * 2000; - return (vertexZabs < DCH_halflengh) && (vertexRsquared > DCH_rin_squared) && (vertexRsquared < DCH_rout_squared); +bool DCHdigi::IsParticleCreatedInsideDriftChamber(const edm4hep::MCParticle& thisParticle) const { + auto vertex = thisParticle.getVertex(); // in mm + auto vertexRsquared = vertex[0] * vertex[0] + vertex[1] * vertex[1]; + auto vertexZabs = std::fabs(vertex[2]); + float DCH_halflengh = dch_data->Lhalf / dd4hep::mm; //2000; + float DCH_rin_squared = std::pow(dch_data->rin / dd4hep::mm, 2); //350 * 350; + float DCH_rout_squared = std::pow(dch_data->rout / dd4hep::mm, 2); //2000 * 2000; + return (vertexZabs < DCH_halflengh) && (vertexRsquared > DCH_rin_squared) && (vertexRsquared < DCH_rout_squared); } std::pair DCHdigi::CalculateClusters(const edm4hep::SimTrackerHit& input_sim_hit) const { - /// vector to accumulate the size of each cluster std::vector ClSz_vector; //_________________SET NECESSARY PARAMETERS FOR THE CLS ALGORITHM-----WALAA_________________// // Parameters needed for the CL Algo //Added by Walaa/////// ///from Createclusters.cpp//// - float Eloss = 0.0; - float EIzp = 15.8; - float ExECl1 = 0; - float cut = 1000; //controlla - float EIzs = 25.6; - float ExECl1totRec = 0; - float rndCorr(0); - const int nhEp = 10; - float hEpcut[10] = {100, 200, 300, 400, 500, 600, 700, 800, 900, 1000}; - int minE = 1000; - int maxE = 10000; - int binE = 1000; - int nhE = (maxE - minE) / binE; - float maxEx0len(0), ExSgmlen(0); + float Eloss = 0.0; + float EIzp = 15.8; + float ExECl1 = 0; + float cut = 1000; //controlla + float EIzs = 25.6; + float ExECl1totRec = 0; + float rndCorr(0); + const int nhEp = 10; + float hEpcut[10] = {100, 200, 300, 400, 500, 600, 700, 800, 900, 1000}; + int minE = 1000; + int maxE = 10000; + int binE = 1000; + int nhE = (maxE - minE) / binE; + float maxEx0len(0), ExSgmlen(0); std::vector CorrpMean; std::vector CorrpSgm; std::vector Corrdgmean; @@ -360,22 +358,22 @@ std::pair DCHdigi::CalculateClusters(const edm4hep::SimTrack std::vector Corrdglsgml; std::vector Corrdglmeang; std::vector Corrdglsgmg; - float maxEx0(0), maxExSlp(0), ExSgmlep(0), ExSgmhad(0); - float MPVEx(0), SgmEx(0), MeanEx1(0), SgmEx1(0), frac(0), Slp(0), CorrSlp(0), CorrInt(0); + float maxEx0(0), maxExSlp(0), ExSgmlep(0), ExSgmhad(0); + float MPVEx(0), SgmEx(0), MeanEx1(0), SgmEx1(0), frac(0), Slp(0), CorrSlp(0), CorrInt(0); /*________________________________________________________________________________*/ - const edm4hep::MCParticle & thisParticle = input_sim_hit.getParticle(); - bool IsSecondaryWithinDCH = IsParticleCreatedInsideDriftChamber(thisParticle); + const edm4hep::MCParticle& thisParticle = input_sim_hit.getParticle(); + bool IsSecondaryWithinDCH = IsParticleCreatedInsideDriftChamber(thisParticle); // Momentum from EDM4hep, in GeV double Momentum = sqrt((input_sim_hit.getMomentum().x * input_sim_hit.getMomentum().x) + (input_sim_hit.getMomentum().y * input_sim_hit.getMomentum().y) + (input_sim_hit.getMomentum().z * input_sim_hit.getMomentum().z)); - int thisparticle_pdgid = thisParticle.getPDG(); - int electron_pdgid = 11; - constexpr double me = 0.511; // electron mass in MeV - constexpr double me_GeV = me*1e-3; // electron mass in GeV + int thisparticle_pdgid = thisParticle.getPDG(); + int electron_pdgid = 11; + constexpr double me = 0.511; // electron mass in MeV + constexpr double me_GeV = me * 1e-3; // electron mass in GeV /// number of clusters, with size > 1 electron int NClp(0); @@ -384,8 +382,7 @@ std::pair DCHdigi::CalculateClusters(const edm4hep::SimTrack int NCl1(0); // TODO Alvaro: gamma rays as secondary are ignored? - if( not IsSecondaryWithinDCH ) - { + if (not IsSecondaryWithinDCH) { // lepton PDG id goes from 11 to 16 (antiparticles have negative id) bool IsLepton = (11 <= abs(thisparticle_pdgid)) && (16 >= abs(thisparticle_pdgid)); if (IsLepton) { @@ -396,8 +393,7 @@ std::pair DCHdigi::CalculateClusters(const edm4hep::SimTrack } double thisparticle_mass = (thisParticle.getMass() / 1000.); // mass in GeV, required in MeV - double bg = Momentum / thisparticle_mass; - + double bg = Momentum / thisparticle_mass; CorrpMean = flData->get_ClSzCorrpmean(bg); CorrpSgm = flData->get_ClSzCorrpsgm(bg); @@ -420,8 +416,10 @@ std::pair DCHdigi::CalculateClusters(const edm4hep::SimTrack CorrSlp = flData->get_ClSzCorrSlp(bg); CorrInt = flData->get_ClSzCorrInt(bg); - double Tmax = (2.0 * me * pow(bg, 2) / (1 + (2.0 * (1 + pow(bg, 2)) * me / thisparticle_mass) + pow(me / thisparticle_mass, 2))) * 1e+6; - float maxEcut = cut; + double Tmax = (2.0 * me * pow(bg, 2) / + (1 + (2.0 * (1 + pow(bg, 2)) * me / thisparticle_mass) + pow(me / thisparticle_mass, 2))) * + 1e+6; + float maxEcut = cut; if (Tmax < maxEcut) { maxEcut = Tmax; } @@ -441,8 +439,8 @@ std::pair DCHdigi::CalculateClusters(const edm4hep::SimTrack exGauss->SetParameter(4, Slp); exGauss->SetRange(0, 90); - float totExECl = 0.0; - float ExECl = 0.0; + float totExECl = 0.0; + float ExECl = 0.0; double LengthTrack = input_sim_hit.getPathLength(); double Etot_per_track = input_sim_hit.getEDep(); LengthTrack *= 0.1; //from mm to cm @@ -459,43 +457,42 @@ std::pair DCHdigi::CalculateClusters(const edm4hep::SimTrack maxExECl = 0.0; } //EIzs const = 25.6 - debug() << "Eloss= " << Eloss << "EIzs= " << EIzs << "EIzp= " << EIzp << "maxExECl= " << maxExECl << "totExECl" - << totExECl << endmsg; - - // The following loop calculate number of clusters of size > 1, NClp - for (int while1counter = 0; Eloss > (EIzp + EIzs) && maxExECl > totExECl && while1counter < 1e6; while1counter++ ) { + debug() << "Eloss= " << Eloss << "EIzs= " << EIzs << "EIzp= " << EIzp << "maxExECl= " << maxExECl << "totExECl" + << totExECl << endmsg; - ExECl = land->GetRandom(0, maxEcut); + // The following loop calculate number of clusters of size > 1, NClp + for (int while1counter = 0; Eloss > (EIzp + EIzs) && maxExECl > totExECl && while1counter < 1e6; while1counter++) { + ExECl = land->GetRandom(0, maxEcut); - if (ExECl > EIzs) { - Eloss -= EIzp; - if (ExECl > (maxExECl - totExECl)) { - ExECl = maxExECl - totExECl; - } - if (ExECl > Eloss) - ExECl = Eloss; - totExECl += ExECl; - Eloss -= ExECl; - NClp++; - //CLSZ - float tmpCorr = 0.0; - for (int i = 0; i < nhEp; ++i) { - if (ExECl >= (i == 0 ? 0 : hEpcut[i - 1]) && ExECl < hEpcut[i]) { - tmpCorr = this->myRandom.Gaus(CorrpMean[i], CorrpSgm[i]); - } - } - int ClSz = TMath::Nint(ExECl * CorrSlp + CorrInt - tmpCorr); - if (ClSz < 2) { - ClSz = 2; + if (ExECl > EIzs) { + Eloss -= EIzp; + if (ExECl > (maxExECl - totExECl)) { + ExECl = maxExECl - totExECl; + } + if (ExECl > Eloss) + ExECl = Eloss; + totExECl += ExECl; + Eloss -= ExECl; + NClp++; + //CLSZ + float tmpCorr = 0.0; + for (int i = 0; i < nhEp; ++i) { + if (ExECl >= (i == 0 ? 0 : hEpcut[i - 1]) && ExECl < hEpcut[i]) { + tmpCorr = this->myRandom.Gaus(CorrpMean[i], CorrpSgm[i]); } - ClSz_vector.push_back(ClSz); } + int ClSz = TMath::Nint(ExECl * CorrSlp + CorrInt - tmpCorr); + if (ClSz < 2) { + ClSz = 2; + } + ClSz_vector.push_back(ClSz); } + } debug() << "Eloss= " << Eloss << "EIzp= " << EIzp << endmsg; // The following loop calculate number of clusters of size 1, NCl1 - for (int while2counter = 0; Eloss >= EIzp && while2counter < 1e6; while2counter++) { + for (int while2counter = 0; Eloss >= EIzp && while2counter < 1e6; while2counter++) { Eloss -= EIzp; ExECl1 = exGauss->GetRandom(); if (ExECl1 > Eloss) { @@ -508,20 +505,20 @@ std::pair DCHdigi::CalculateClusters(const edm4hep::SimTrack ClSz_vector.push_back(1); } - } //-- end if particle is not secondary + } //-- end if particle is not secondary // if particle is a delta electron created inside the drift chamber int NCld(0); - if (IsSecondaryWithinDCH && electron_pdgid == thisparticle_pdgid) { + if (IsSecondaryWithinDCH && electron_pdgid == thisparticle_pdgid) { // 1 delta ray cause 1 cluster NCld (d=delta) NCld = 1; // Ekdelta in keV - float Ekdelta = (TMath::Sqrt(Momentum * Momentum + me_GeV * me_GeV) - me_GeV) * 1e6; + float Ekdelta = (TMath::Sqrt(Momentum * Momentum + me_GeV * me_GeV) - me_GeV) * 1e6; // TODO Alvaro: what is this for? { float tmpCl; - int tmphE = (Ekdelta - minE) / binE; + int tmphE = (Ekdelta - minE) / binE; if (tmphE >= nhE) tmphE = nhE - 1; if (tmphE == nhE - 1) { @@ -537,13 +534,11 @@ std::pair DCHdigi::CalculateClusters(const edm4hep::SimTrack int ClSz = TMath::Nint(Ekdelta * CorrSlp + CorrInt - tmpCl); // TODO Alvaro: should it be 1 instead? - if (ClSz < 2) - { + if (ClSz < 2) { ClSz = 2; } ClSz_vector.push_back(ClSz); } - } // conclusion: if hit caused by delta electron, NCld = 1, number of electrons ClSz=2 @@ -553,8 +548,8 @@ std::pair DCHdigi::CalculateClusters(const edm4hep::SimTrack // value to be returned, total number of electrons (cluster size) int total_number_of_electrons_over_all_clusters = 0; - for( auto cluster_size : ClSz_vector) + for (auto cluster_size : ClSz_vector) total_number_of_electrons_over_all_clusters += cluster_size; - return { total_number_of_clusters , total_number_of_electrons_over_all_clusters }; + return {total_number_of_clusters, total_number_of_electrons_over_all_clusters}; } From be57d8cdbcb051e8290e045d063baae74c0178ff Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Mon, 11 Nov 2024 18:02:18 +0100 Subject: [PATCH 41/56] include vector of cluster sizes in the data extension --- DCHdigi/dataFormatExtension/driftChamberHit.yaml | 3 ++- DCHdigi/include/DCHdigi.h | 4 ++-- DCHdigi/src/DCHdigi.cpp | 15 +++++++++++---- .../compact/DCH_standalone_o1_v02.xml | 14 +++++++------- DCHdigi/test/test_DCHdigi/sim_steering.py | 9 ++++++--- 5 files changed, 28 insertions(+), 17 deletions(-) diff --git a/DCHdigi/dataFormatExtension/driftChamberHit.yaml b/DCHdigi/dataFormatExtension/driftChamberHit.yaml index 891045c..0edf251 100644 --- a/DCHdigi/dataFormatExtension/driftChamberHit.yaml +++ b/DCHdigi/dataFormatExtension/driftChamberHit.yaml @@ -57,7 +57,8 @@ datatypes: - edm4hep::Vector3d directionSW // direction of SW - float distanceToWire // distance hit-wire [mm] - uint32_t nCluster // number of clusters associated to this hit - - uint32_t nElectronsTotal // number of electrons for all the nCluster + VectorMembers: + - uint16_t nElectrons // number of electrons for each cluster extension::MCRecoDriftChamberDigiV2Association: Description: "Association between a DriftChamberDigi and the corresponding simulated hit" diff --git a/DCHdigi/include/DCHdigi.h b/DCHdigi/include/DCHdigi.h index 2ea9695..e680459 100644 --- a/DCHdigi/include/DCHdigi.h +++ b/DCHdigi/include/DCHdigi.h @@ -172,8 +172,8 @@ struct DCHdigi final /// pointer to wrapper class, which contains the cluster size and number distributions AlgData* flData; - /// code developed by Walaa for calculating number of clusters and cluster size - std::pair CalculateClusters(const edm4hep::SimTrackerHit& input_sim_hit) const; + /// code developed by Walaa for calculating number of clusters and cluster size of each one + std::pair> CalculateClusters(const edm4hep::SimTrackerHit& input_sim_hit) const; bool IsParticleCreatedInsideDriftChamber(const edm4hep::MCParticle &) const ; diff --git a/DCHdigi/src/DCHdigi.cpp b/DCHdigi/src/DCHdigi.cpp index 04c41fc..7d04625 100644 --- a/DCHdigi/src/DCHdigi.cpp +++ b/DCHdigi/src/DCHdigi.cpp @@ -150,7 +150,7 @@ DCHdigi::operator()(const edm4hep::SimTrackerHitCollection& input_sim_hits, auto directionSW = Convert_TVector3_to_EDM4hepVector(wire_direction_ez, 1. / MM_TO_CM); float distanceToWire = distanceToWire_smeared / MM_TO_CM; - auto [nCluster, nElectronsTotal] = CalculateClusters(input_sim_hit); + auto [nCluster, nElectrons_v] = CalculateClusters(input_sim_hit); extension::MutableDriftChamberDigiV2 oDCHdigihit; oDCHdigihit.setCellID(input_sim_hit.getCellID()); @@ -163,7 +163,10 @@ DCHdigi::operator()(const edm4hep::SimTrackerHitCollection& input_sim_hits, oDCHdigihit.setDirectionSW(directionSW); oDCHdigihit.setDistanceToWire(distanceToWire); oDCHdigihit.setNCluster(nCluster); - oDCHdigihit.setNElectronsTotal(nElectronsTotal); + // int nElectronsTotal = std::accumulate( nElectrons_v.begin(), nElectrons_v.end(), 0); + // oDCHdigihit.setNElectronsTotal(nElectronsTotal); + for( auto ne : nElectrons_v ) + oDCHdigihit.addToNElectrons(ne); output_digi_hits.push_back(oDCHdigihit); @@ -328,7 +331,7 @@ bool DCHdigi::IsParticleCreatedInsideDriftChamber(const edm4hep::MCParticle& thi return (vertexZabs < DCH_halflengh) && (vertexRsquared > DCH_rin_squared) && (vertexRsquared < DCH_rout_squared); } -std::pair DCHdigi::CalculateClusters(const edm4hep::SimTrackerHit& input_sim_hit) const { +std::pair > DCHdigi::CalculateClusters(const edm4hep::SimTrackerHit& input_sim_hit) const { /// vector to accumulate the size of each cluster std::vector ClSz_vector; //_________________SET NECESSARY PARAMETERS FOR THE CLS ALGORITHM-----WALAA_________________// @@ -546,10 +549,14 @@ std::pair DCHdigi::CalculateClusters(const edm4hep::SimTrack int total_number_of_clusters = NCl1 + NClp + NCld; debug() << "Ncl= " << total_number_of_clusters << " NCl1= " << NCl1 << "NClp= " << NClp << "NCld= " << NCld << endmsg; + if( ClSz_vector.size() != total_number_of_clusters ) + debug() << "Array of cluster sizes does not match total number of clusters\n"; + // value to be returned, total number of electrons (cluster size) int total_number_of_electrons_over_all_clusters = 0; for (auto cluster_size : ClSz_vector) total_number_of_electrons_over_all_clusters += cluster_size; - return {total_number_of_clusters, total_number_of_electrons_over_all_clusters}; + // return {total_number_of_clusters, total_number_of_electrons_over_all_clusters}; + return {total_number_of_clusters, ClSz_vector}; } diff --git a/DCHdigi/test/test_DCHdigi/compact/DCH_standalone_o1_v02.xml b/DCHdigi/test/test_DCHdigi/compact/DCH_standalone_o1_v02.xml index 8f48e4f..0ec10a3 100644 --- a/DCHdigi/test/test_DCHdigi/compact/DCH_standalone_o1_v02.xml +++ b/DCHdigi/test/test_DCHdigi/compact/DCH_standalone_o1_v02.xml @@ -92,13 +92,13 @@ - - - + + + - + @@ -112,7 +112,7 @@ region="DCH_region" limits="DCH_limits" buildLayers="True" - printExcelTable="False" + printExcelTable="True" > @@ -136,8 +136,8 @@ Date: Wed, 13 Nov 2024 09:05:25 +0100 Subject: [PATCH 42/56] add few comments --- DCHdigi/include/DCHdigi.h | 1 + DCHdigi/src/DCHdigi.cpp | 20 +++++++++++--------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/DCHdigi/include/DCHdigi.h b/DCHdigi/include/DCHdigi.h index e680459..80b69a2 100644 --- a/DCHdigi/include/DCHdigi.h +++ b/DCHdigi/include/DCHdigi.h @@ -129,6 +129,7 @@ struct DCHdigi final // Gaussian random number generator used for the smearing of the xy position, in cm! mutable std::normal_distribution m_gauss_xy_cm; + /// members with internal state (such as random engines) must be defined thread local inline static thread_local TRandom3 myRandom; //------------------------------------------------------------------ // ancillary functions diff --git a/DCHdigi/src/DCHdigi.cpp b/DCHdigi/src/DCHdigi.cpp index 7d04625..474be15 100644 --- a/DCHdigi/src/DCHdigi.cpp +++ b/DCHdigi/src/DCHdigi.cpp @@ -163,8 +163,10 @@ DCHdigi::operator()(const edm4hep::SimTrackerHitCollection& input_sim_hits, oDCHdigihit.setDirectionSW(directionSW); oDCHdigihit.setDistanceToWire(distanceToWire); oDCHdigihit.setNCluster(nCluster); - // int nElectronsTotal = std::accumulate( nElectrons_v.begin(), nElectrons_v.end(), 0); - // oDCHdigihit.setNElectronsTotal(nElectronsTotal); + // to return the total number of electrons within the step, do the following: + // int nElectronsTotal = std::accumulate( nElectrons_v.begin(), nElectrons_v.end(), 0); + // oDCHdigihit.setNElectronsTotal(nElectronsTotal); + // to copy the vector of each cluster size to the EDM4hep data extension, do the following: for( auto ne : nElectrons_v ) oDCHdigihit.addToNElectrons(ne); @@ -220,6 +222,11 @@ void DCHdigi::PrintConfiguration(std::ostream& io) { io << "\tCluster distributions taken from: " << m_fileDataAlg.value().c_str() << "\n"; io << "\tResolution along the wire (mm): " << m_z_resolution.value() << "\n"; io << "\tResolution perp. to the wire (mm): " << m_xy_resolution.value() << "\n"; + io << "\tCreate debug histograms: " << ( m_create_debug_histos.value() ? "true" : "false" ) << "\n"; + if( true == m_create_debug_histos.value() ) + io << "\t\t|--Name of output file with debug histograms: " << m_out_debug_filename.value() << "\n"; + + return; } @@ -332,7 +339,7 @@ bool DCHdigi::IsParticleCreatedInsideDriftChamber(const edm4hep::MCParticle& thi } std::pair > DCHdigi::CalculateClusters(const edm4hep::SimTrackerHit& input_sim_hit) const { - /// vector to accumulate the size of each cluster + /// vector to accumulate the size (number of electrons) of each cluster std::vector ClSz_vector; //_________________SET NECESSARY PARAMETERS FOR THE CLS ALGORITHM-----WALAA_________________// @@ -549,14 +556,9 @@ std::pair > DCHdigi::CalculateClusters(const edm4hep: int total_number_of_clusters = NCl1 + NClp + NCld; debug() << "Ncl= " << total_number_of_clusters << " NCl1= " << NCl1 << "NClp= " << NClp << "NCld= " << NCld << endmsg; - if( ClSz_vector.size() != total_number_of_clusters ) + if( ClSz_vector.size() != std::size_t(total_number_of_clusters) ) debug() << "Array of cluster sizes does not match total number of clusters\n"; - // value to be returned, total number of electrons (cluster size) - int total_number_of_electrons_over_all_clusters = 0; - for (auto cluster_size : ClSz_vector) - total_number_of_electrons_over_all_clusters += cluster_size; - // return {total_number_of_clusters, total_number_of_electrons_over_all_clusters}; return {total_number_of_clusters, ClSz_vector}; } From ddde328e43d722f9775a9d2d4f72aaa43d777489 Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Wed, 13 Nov 2024 14:26:02 +0100 Subject: [PATCH 43/56] move initialization of distributions to the main scope of the CalculateClusters function --- DCHdigi/src/DCHdigi.cpp | 73 ++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 33 deletions(-) diff --git a/DCHdigi/src/DCHdigi.cpp b/DCHdigi/src/DCHdigi.cpp index 474be15..7e306aa 100644 --- a/DCHdigi/src/DCHdigi.cpp +++ b/DCHdigi/src/DCHdigi.cpp @@ -339,6 +339,12 @@ bool DCHdigi::IsParticleCreatedInsideDriftChamber(const edm4hep::MCParticle& thi } std::pair > DCHdigi::CalculateClusters(const edm4hep::SimTrackerHit& input_sim_hit) const { + + const edm4hep::MCParticle& thisParticle = input_sim_hit.getParticle(); + // if gamma, optical photon, or other particle with null mass, return zero clusters + if( 22 == abs(thisParticle.getPDG()) || 0 == thisParticle.getMass() ) + return {0., std::vector{} }; + /// vector to accumulate the size (number of electrons) of each cluster std::vector ClSz_vector; //_________________SET NECESSARY PARAMETERS FOR THE CLS ALGORITHM-----WALAA_________________// @@ -372,7 +378,6 @@ std::pair > DCHdigi::CalculateClusters(const edm4hep: float MPVEx(0), SgmEx(0), MeanEx1(0), SgmEx1(0), frac(0), Slp(0), CorrSlp(0), CorrInt(0); /*________________________________________________________________________________*/ - const edm4hep::MCParticle& thisParticle = input_sim_hit.getParticle(); bool IsSecondaryWithinDCH = IsParticleCreatedInsideDriftChamber(thisParticle); // Momentum from EDM4hep, in GeV @@ -391,7 +396,39 @@ std::pair > DCHdigi::CalculateClusters(const edm4hep: /// number of clusters, with size = 1 electron int NCl1(0); - // TODO Alvaro: gamma rays as secondary are ignored? + //___________________________________________________________________ + double thisparticle_mass = (thisParticle.getMass() / 1000.); // mass in GeV, required in MeV + double bg = Momentum / thisparticle_mass; + + CorrpMean = flData->get_ClSzCorrpmean(bg); + CorrpSgm = flData->get_ClSzCorrpsgm(bg); + Corrdgmean = flData->get_ClSzCorrdgmean(bg); + Corrdgsgm = flData->get_ClSzCorrdgsgm(bg); + Corrdglfrac = flData->get_ClSzCorrdglfrac(bg); + Corrdglmpvl = flData->get_ClSzCorrdglmpvl(bg); + Corrdglsgml = flData->get_ClSzCorrdglsgml(bg); + Corrdglmeang = flData->get_ClSzCorrdglmeang(bg); + Corrdglsgmg = flData->get_ClSzCorrdglsgmg(bg); + maxEx0 = flData->get_maxEx0(bg); //379.4 electron 100 gev + maxExSlp = flData->get_maxExSlp(); + + MPVEx = flData->get_MPVExtra(bg); //103.2 + SgmEx = flData->get_SgmExtra(bg); //28.5;// + MeanEx1 = flData->get_MeanExtra1(bg); //13.8;// + SgmEx1 = flData->get_SgmExtra1(bg); //9.72;// + frac = flData->get_FracExtra1(bg); //0.13;// + Slp = flData->get_SlopeExtra1(bg); //7.95;// + CorrSlp = flData->get_ClSzCorrSlp(bg); + CorrInt = flData->get_ClSzCorrInt(bg); + + double Tmax = (2.0 * me * pow(bg, 2) / + (1 + (2.0 * (1 + pow(bg, 2)) * me / thisparticle_mass) + pow(me / thisparticle_mass, 2))) * + 1e+6; + float maxEcut = cut; + if (Tmax < maxEcut) { + maxEcut = Tmax; + } + //___________________________________________________________________ if (not IsSecondaryWithinDCH) { // lepton PDG id goes from 11 to 16 (antiparticles have negative id) bool IsLepton = (11 <= abs(thisparticle_pdgid)) && (16 >= abs(thisparticle_pdgid)); @@ -402,37 +439,7 @@ std::pair > DCHdigi::CalculateClusters(const edm4hep: ExSgmhad = flData->get_ExSgmhad(); } - double thisparticle_mass = (thisParticle.getMass() / 1000.); // mass in GeV, required in MeV - double bg = Momentum / thisparticle_mass; - - CorrpMean = flData->get_ClSzCorrpmean(bg); - CorrpSgm = flData->get_ClSzCorrpsgm(bg); - Corrdgmean = flData->get_ClSzCorrdgmean(bg); - Corrdgsgm = flData->get_ClSzCorrdgsgm(bg); - Corrdglfrac = flData->get_ClSzCorrdglfrac(bg); - Corrdglmpvl = flData->get_ClSzCorrdglmpvl(bg); - Corrdglsgml = flData->get_ClSzCorrdglsgml(bg); - Corrdglmeang = flData->get_ClSzCorrdglmeang(bg); - Corrdglsgmg = flData->get_ClSzCorrdglsgmg(bg); - maxEx0 = flData->get_maxEx0(bg); //379.4 electron 100 gev - maxExSlp = flData->get_maxExSlp(); - - MPVEx = flData->get_MPVExtra(bg); //103.2 - SgmEx = flData->get_SgmExtra(bg); //28.5;// - MeanEx1 = flData->get_MeanExtra1(bg); //13.8;// - SgmEx1 = flData->get_SgmExtra1(bg); //9.72;// - frac = flData->get_FracExtra1(bg); //0.13;// - Slp = flData->get_SlopeExtra1(bg); //7.95;// - CorrSlp = flData->get_ClSzCorrSlp(bg); - CorrInt = flData->get_ClSzCorrInt(bg); - - double Tmax = (2.0 * me * pow(bg, 2) / - (1 + (2.0 * (1 + pow(bg, 2)) * me / thisparticle_mass) + pow(me / thisparticle_mass, 2))) * - 1e+6; - float maxEcut = cut; - if (Tmax < maxEcut) { - maxEcut = Tmax; - } + /*________________________________________________________________________________*/ TF1* land = new TF1("land", "landaun"); From 6ef9e945e4cfef71309334cf117e0431b56294db Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Wed, 13 Nov 2024 14:27:45 +0100 Subject: [PATCH 44/56] add protection against zero energy hit --- DCHdigi/src/DCHdigi.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DCHdigi/src/DCHdigi.cpp b/DCHdigi/src/DCHdigi.cpp index 7e306aa..34bbe8a 100644 --- a/DCHdigi/src/DCHdigi.cpp +++ b/DCHdigi/src/DCHdigi.cpp @@ -341,8 +341,8 @@ bool DCHdigi::IsParticleCreatedInsideDriftChamber(const edm4hep::MCParticle& thi std::pair > DCHdigi::CalculateClusters(const edm4hep::SimTrackerHit& input_sim_hit) const { const edm4hep::MCParticle& thisParticle = input_sim_hit.getParticle(); - // if gamma, optical photon, or other particle with null mass, return zero clusters - if( 22 == abs(thisParticle.getPDG()) || 0 == thisParticle.getMass() ) + // if gamma, optical photon, or other particle with null mass, or hit with zero energy deposited, return zero clusters + if( 22 == abs(thisParticle.getPDG()) || 0 == thisParticle.getMass() || 0 == input_sim_hit.getEDep() ) return {0., std::vector{} }; /// vector to accumulate the size (number of electrons) of each cluster From 560bcef04542629af1ee397cf8fec668864df62a Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Wed, 13 Nov 2024 15:12:11 +0100 Subject: [PATCH 45/56] change direction and random seed for DDSim steering file --- DCHdigi/test/test_DCHdigi/sim_steering.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/DCHdigi/test/test_DCHdigi/sim_steering.py b/DCHdigi/test/test_DCHdigi/sim_steering.py index 061524a..1796a21 100644 --- a/DCHdigi/test/test_DCHdigi/sim_steering.py +++ b/DCHdigi/test/test_DCHdigi/sim_steering.py @@ -239,7 +239,7 @@ ################################################################################ ## direction of the particle gun, 3 vector -SIM.gun.direction = (1, 0.9, 0) +SIM.gun.direction = (1,1,1) ## choose the distribution of the random direction for theta ## @@ -257,7 +257,7 @@ ## Total energy (including mass) for the particle gun. ## ## If not None, it will overwrite the setting of momentumMin and momentumMax -SIM.gun.energy = '5*GeV' +SIM.gun.energy = '10*GeV' ## Maximal pseudorapidity for random distibution (overrides thetaMin) SIM.gun.etaMax = None @@ -554,11 +554,11 @@ ## If True, calculate random seed for each event basedon eventID and runID ## Allows reproducibility even whenSkippingEvents -SIM.random.enableEventSeed = False +SIM.random.enableEventSeed = True SIM.random.file = None SIM.random.luxury = 1 SIM.random.replace_gRandom = True -SIM.random.seed = None +SIM.random.seed = 123 SIM.random.type = None From 2d269e05ea9b1a8d3af67a40dc530b1e27fa9f4f Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Thu, 14 Nov 2024 13:24:03 +0100 Subject: [PATCH 46/56] add version v01 suffix to digitizer class name --- DCHdigi/include/{DCHdigi.h => DCHdigi_v01.h} | 14 +++++----- DCHdigi/src/{DCHdigi.cpp => DCHdigi_v01.cpp} | 28 ++++++++++---------- DCHdigi/test/test_DCHdigi/runDCHdigi.py | 4 +-- 3 files changed, 23 insertions(+), 23 deletions(-) rename DCHdigi/include/{DCHdigi.h => DCHdigi_v01.h} (97%) rename DCHdigi/src/{DCHdigi.cpp => DCHdigi_v01.cpp} (95%) diff --git a/DCHdigi/include/DCHdigi.h b/DCHdigi/include/DCHdigi_v01.h similarity index 97% rename from DCHdigi/include/DCHdigi.h rename to DCHdigi/include/DCHdigi_v01.h index 80b69a2..022abb3 100644 --- a/DCHdigi/include/DCHdigi.h +++ b/DCHdigi/include/DCHdigi_v01.h @@ -1,4 +1,4 @@ -/** ======= DCHdigi ========== +/** ======= DCHdigi_v01 ========== * Gaudi Algorithm for DCH digitization * * @@ -31,8 +31,8 @@ *
*/ -#ifndef DCHDIGI_H -#define DCHDIGI_H +#ifndef DCHDIGI_V01_H +#define DCHDIGI_V01_H // Gaudi Transformer baseclass headers #include "Gaudi/Property.h" @@ -59,7 +59,7 @@ #include #include -// data extension for the DCH v2 +// data extension for detector DCH_v2 #include "DDRec/DCH_info.h" // ROOT headers @@ -74,11 +74,11 @@ /// constant to convert from mm (EDM4hep) to DD4hep (cm) constexpr double MM_TO_CM = 0.1; -struct DCHdigi final +struct DCHdigi_v01 final : k4FWCore::MultiTransformer< std::tuple( const edm4hep::SimTrackerHitCollection&, const edm4hep::EventHeaderCollection&)> { - DCHdigi(const std::string& name, ISvcLocator* svcLoc); + DCHdigi_v01(const std::string& name, ISvcLocator* svcLoc); StatusCode initialize() override; StatusCode finalize() override; @@ -201,6 +201,6 @@ struct DCHdigi final TH1D* hSxy; }; -DECLARE_COMPONENT(DCHdigi); +DECLARE_COMPONENT(DCHdigi_v01); #endif diff --git a/DCHdigi/src/DCHdigi.cpp b/DCHdigi/src/DCHdigi_v01.cpp similarity index 95% rename from DCHdigi/src/DCHdigi.cpp rename to DCHdigi/src/DCHdigi_v01.cpp index 34bbe8a..0ec1742 100644 --- a/DCHdigi/src/DCHdigi.cpp +++ b/DCHdigi/src/DCHdigi_v01.cpp @@ -1,4 +1,4 @@ -#include "DCHdigi.h" +#include "DCHdigi_v01.h" // STL #include @@ -10,7 +10,7 @@ /////////////////////// DCHdigi constructor //////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// // -- KeyValues("name of the variable that holds the name of the collection exposed in the python steering file", {"default name for the collection"}), -DCHdigi::DCHdigi(const std::string& name, ISvcLocator* svcLoc) +DCHdigi_v01::DCHdigi_v01(const std::string& name, ISvcLocator* svcLoc) : MultiTransformer(name, svcLoc, { KeyValues("DCH_simhits", {""}), @@ -25,7 +25,7 @@ DCHdigi::DCHdigi(const std::string& name, ISvcLocator* svcLoc) /////////////////////////////////////////////////////////////////////////////////////// /////////////////////// initialize //////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// -StatusCode DCHdigi::initialize() { +StatusCode DCHdigi_v01::initialize() { if (!m_uidSvc) ThrowException("Unable to get UniqueIDGenSvc"); @@ -90,7 +90,7 @@ StatusCode DCHdigi::initialize() { /////////////////////// operator() //////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// std::tuple -DCHdigi::operator()(const edm4hep::SimTrackerHitCollection& input_sim_hits, +DCHdigi_v01::operator()(const edm4hep::SimTrackerHitCollection& input_sim_hits, const edm4hep::EventHeaderCollection& headers) const { // initialize seed for random engine this->PrepareRandomEngine(headers); @@ -188,7 +188,7 @@ DCHdigi::operator()(const edm4hep::SimTrackerHitCollection& input_sim_hits, /////////////////////////////////////////////////////////////////////////////////////// /////////////////////// finalize ////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// -StatusCode DCHdigi::finalize() { +StatusCode DCHdigi_v01::finalize() { if (m_create_debug_histos.value()) { std::unique_ptr ofile{TFile::Open(m_out_debug_filename.value().c_str(), "recreate")}; ofile->cd(); @@ -204,7 +204,7 @@ StatusCode DCHdigi::finalize() { /////////////////////////////////////////////////////////////////////////////////////// /////////////////////// ThrowException //////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// -void DCHdigi::ThrowException(std::string s) const { +void DCHdigi_v01::ThrowException(std::string s) const { error() << s.c_str() << endmsg; throw std::runtime_error(s); } @@ -212,7 +212,7 @@ void DCHdigi::ThrowException(std::string s) const { /////////////////////////////////////////////////////////////////////////////////////// /////////////////////// PrintConfiguration //////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// -void DCHdigi::PrintConfiguration(std::ostream& io) { +void DCHdigi_v01::PrintConfiguration(std::ostream& io) { io << "DCHdigi will use the following components:\n"; io << "\tGeometry Service: " << m_geoSvcName.value().c_str() << "\n"; io << "\tUID Service: " << m_uidSvcName.value().c_str() << "\n"; @@ -230,7 +230,7 @@ void DCHdigi::PrintConfiguration(std::ostream& io) { return; } -void DCHdigi::PrepareRandomEngine(const edm4hep::EventHeaderCollection& headers) const { +void DCHdigi_v01::PrepareRandomEngine(const edm4hep::EventHeaderCollection& headers) const { uint32_t evt_n = headers[0].getEventNumber(); uint32_t run_n = headers[0].getRunNumber(); size_t seed = m_uidSvc->getUniqueID(evt_n, run_n, this->name()); @@ -245,7 +245,7 @@ void DCHdigi::PrepareRandomEngine(const edm4hep::EventHeaderCollection& headers) ///// Ancillary functions for calculating the distance to the wire //////// /////////////////////////////////////////////////////////////////////////////////////// -TVector3 DCHdigi::Calculate_wire_vector_ez(int ilayer, int nphi) const { +TVector3 DCHdigi_v01::Calculate_wire_vector_ez(int ilayer, int nphi) const { auto& l = this->dch_data->database.at(ilayer); // See original paper Hoshina et al, Computer Physics Communications 153 (2003) 3 @@ -288,7 +288,7 @@ TVector3 DCHdigi::Calculate_wire_vector_ez(int ilayer, int nphi) const { return (p2 - p1).Unit(); } -TVector3 DCHdigi::Calculate_wire_z0_point(int ilayer, int nphi) const { +TVector3 DCHdigi_v01::Calculate_wire_z0_point(int ilayer, int nphi) const { auto& l = this->dch_data->database.at(ilayer); double rz0 = l.radius_sw_z0; TVector3 p1(rz0, 0, 0); @@ -298,7 +298,7 @@ TVector3 DCHdigi::Calculate_wire_z0_point(int ilayer, int nphi) const { } // calculate phi rotation of whole twisted tube, ie, rotation at z=0 -double DCHdigi::Calculate_wire_phi_z0(int ilayer, int nphi) const { +double DCHdigi_v01::Calculate_wire_phi_z0(int ilayer, int nphi) const { auto& l = this->dch_data->database.at(ilayer); int ncells = l.nwires / 2; double phistep = TMath::TwoPi() / ncells; @@ -309,7 +309,7 @@ double DCHdigi::Calculate_wire_phi_z0(int ilayer, int nphi) const { /////////////////////////////////////////////////////////////////////////////////////// /////////////////////// Calculate vector from hit position to wire ///////////////// /////////////////////////////////////////////////////////////////////////////////////// -TVector3 DCHdigi::Calculate_hitpos_to_wire_vector(int ilayer, int nphi, const TVector3& hit_position /*in cm*/) const { +TVector3 DCHdigi_v01::Calculate_hitpos_to_wire_vector(int ilayer, int nphi, const TVector3& hit_position /*in cm*/) const { // Solution distance from a point to a line given here: // https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line#Vector_formulation TVector3 n = this->Calculate_wire_vector_ez(ilayer, nphi); @@ -328,7 +328,7 @@ TVector3 DCHdigi::Calculate_hitpos_to_wire_vector(int ilayer, int nphi, const TV /////////////////////// CalculateNClusters //////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// -bool DCHdigi::IsParticleCreatedInsideDriftChamber(const edm4hep::MCParticle& thisParticle) const { +bool DCHdigi_v01::IsParticleCreatedInsideDriftChamber(const edm4hep::MCParticle& thisParticle) const { auto vertex = thisParticle.getVertex(); // in mm auto vertexRsquared = vertex[0] * vertex[0] + vertex[1] * vertex[1]; auto vertexZabs = std::fabs(vertex[2]); @@ -338,7 +338,7 @@ bool DCHdigi::IsParticleCreatedInsideDriftChamber(const edm4hep::MCParticle& thi return (vertexZabs < DCH_halflengh) && (vertexRsquared > DCH_rin_squared) && (vertexRsquared < DCH_rout_squared); } -std::pair > DCHdigi::CalculateClusters(const edm4hep::SimTrackerHit& input_sim_hit) const { +std::pair > DCHdigi_v01::CalculateClusters(const edm4hep::SimTrackerHit& input_sim_hit) const { const edm4hep::MCParticle& thisParticle = input_sim_hit.getParticle(); // if gamma, optical photon, or other particle with null mass, or hit with zero energy deposited, return zero clusters diff --git a/DCHdigi/test/test_DCHdigi/runDCHdigi.py b/DCHdigi/test/test_DCHdigi/runDCHdigi.py index 8a59ade..5d1939f 100644 --- a/DCHdigi/test/test_DCHdigi/runDCHdigi.py +++ b/DCHdigi/test/test_DCHdigi/runDCHdigi.py @@ -16,8 +16,8 @@ geoservice = GeoSvc("GeoSvc") geoservice.detectors = ['./compact/DCH_standalone_o1_v02.xml'] -from Configurables import DCHdigi -DCHdigi = DCHdigi("DCHdigi") +from Configurables import DCHdigi_v01 +DCHdigi = DCHdigi_v01("DCHdigi") DCHdigi.DCH_simhits=["DCHCollection"] DCHdigi.DCH_name="DCH_v2" DCHdigi.fileDataAlg="DataAlgFORGEANT.root" From 018f172c313c722a1cc45b18681073e06e5e1682 Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Thu, 14 Nov 2024 13:55:09 +0100 Subject: [PATCH 47/56] add protection against negative values --- DCHdigi/src/DCHdigi_v01.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/DCHdigi/src/DCHdigi_v01.cpp b/DCHdigi/src/DCHdigi_v01.cpp index 0ec1742..8809072 100644 --- a/DCHdigi/src/DCHdigi_v01.cpp +++ b/DCHdigi/src/DCHdigi_v01.cpp @@ -29,7 +29,12 @@ StatusCode DCHdigi_v01::initialize() { if (!m_uidSvc) ThrowException("Unable to get UniqueIDGenSvc"); + if( 0 > m_z_resolution.value() ) + ThrowException("Z resolution input value can not be negative!"); m_gauss_z_cm = std::normal_distribution(0., m_z_resolution.value() * MM_TO_CM); + + if( 0 > m_xy_resolution.value() ) + ThrowException("Radial (XY) resolution input value can not be negative!"); m_gauss_xy_cm = std::normal_distribution(0., m_xy_resolution.value() * MM_TO_CM); //----------------- From 6ca9321b3494fc124747850e8d21da10ab61fc4e Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Thu, 14 Nov 2024 13:55:18 +0100 Subject: [PATCH 48/56] add readme --- DCHdigi/README.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 DCHdigi/README.md diff --git a/DCHdigi/README.md b/DCHdigi/README.md new file mode 100644 index 0000000..2978f3a --- /dev/null +++ b/DCHdigi/README.md @@ -0,0 +1,20 @@ +# Drift chamber (DCH) digitizers + +## DCHsimpleDigitizer + +* Similar to DCHdigi_v01, but it uses the placement matrix of the wires to apply the smearing along/perpendicular to the sense wire +* No cluster counting information added into the digitized output +* It relies on a dedicated data extension, similar to DCHdigi_v01 + +## DCHdigi description + +* Each simulated hit is transformed into a digitized hit +* The digitized hit position is the projection of the simulated hit position onto the sense wire (at the center of the cell) +* Smearing of the digitized hit position along the wire and radially is done according to the input parameter values (`zResolution_mm1` and `xyResolution_mm`, respectively) +* Number of clusters and their size is derived from file containing precalculated distributions, specified by the parameter `fileDataAlg`, and implemented as the option 3 described in F. Cuna et al, arXiv:2105.07064 +* Debug histograms are created if `create_debug_histograms` option is enabled (output file name can be given) +* Stand alone test run simulation of the drift chamber based on twisted tubes, and then apply the digitizer. Dedicated directory with all the files needed is given in `DCHdigi/test/test_DCHdigi/` +* It requires that the cellID contain the layer and number of cell within the layer (nphi). It does not matter if the segmentation comes from geometrical segmentation by using twisted tubes and hyperboloids (and the cellID is created out of volume IDs), or the segmentation is virtual DD4hep segmentation +* New digitized hit class is used as an EDM4hep data extension, to be integrated into EDM4hep +* Random number generator uses the seeds calculated on an event basis by the UID service, from the podio header information (run/event number) +* At the moment, only one version: v01 From f8bc735b8d19962e05d992b4bc1b2ac999eb0203 Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Fri, 22 Nov 2024 11:27:40 +0100 Subject: [PATCH 49/56] ancillary functions to calculate wire positions moved to data extension --- DCHdigi/include/DCHdigi_v01.h | 10 +---- DCHdigi/src/DCHdigi_v01.cpp | 81 ----------------------------------- 2 files changed, 2 insertions(+), 89 deletions(-) diff --git a/DCHdigi/include/DCHdigi_v01.h b/DCHdigi/include/DCHdigi_v01.h index 022abb3..81bb291 100644 --- a/DCHdigi/include/DCHdigi_v01.h +++ b/DCHdigi/include/DCHdigi_v01.h @@ -143,7 +143,8 @@ struct DCHdigi_v01 final void ThrowException(std::string s) const; int CalculateLayerFromCellID(dd4hep::DDSegmentation::CellID id) const { - return m_decoder->get(id, "layer") + dch_data->nlayersPerSuperlayer * m_decoder->get(id, "superlayer") + 1; + //return m_decoder->get(id, "layer") + dch_data->nlayersPerSuperlayer * m_decoder->get(id, "superlayer") + 1; + return dch_data->CalculateILayerFromCellIDFields( m_decoder->get(id, "layer"), m_decoder->get(id, "superlayer") ); } int CalculateNphiFromCellID(dd4hep::DDSegmentation::CellID id) const { return m_decoder->get(id, "nphi"); } @@ -155,13 +156,6 @@ struct DCHdigi_v01 final return {v.x() * scale, v.y() * scale, v.z() * scale}; }; - // the following functions should be upstreamed to the data extension at DD4hep - // to avoid code duplication and keep it centralized - TVector3 Calculate_hitpos_to_wire_vector(int ilayer, int nphi, const TVector3& hit_position /*in cm*/) const; - TVector3 Calculate_wire_vector_ez(int ilayer, int nphi) const; - TVector3 Calculate_wire_z0_point(int ilayer, int nphi) const; - double Calculate_wire_phi_z0(int ilayer, int nphi) const; - //------------------------------------------------------------------ // cluster calculation, developed by Walaa diff --git a/DCHdigi/src/DCHdigi_v01.cpp b/DCHdigi/src/DCHdigi_v01.cpp index 8809072..ab53870 100644 --- a/DCHdigi/src/DCHdigi_v01.cpp +++ b/DCHdigi/src/DCHdigi_v01.cpp @@ -246,88 +246,7 @@ void DCHdigi_v01::PrepareRandomEngine(const edm4hep::EventHeaderCollection& head myRandom.Rndm(); } -/////////////////////////////////////////////////////////////////////////////////////// -///// Ancillary functions for calculating the distance to the wire //////// -/////////////////////////////////////////////////////////////////////////////////////// - -TVector3 DCHdigi_v01::Calculate_wire_vector_ez(int ilayer, int nphi) const { - auto& l = this->dch_data->database.at(ilayer); - - // See original paper Hoshina et al, Computer Physics Communications 153 (2003) 3 - // eq. 2.9, for the definition of ez, vector along the wire - - // initialize some variables - int stereosign = l.StereoSign(); - double rz0 = l.radius_sw_z0; - double dphi = dch_data->twist_angle; - // kappa is the same as in eq. 2.9 - double kappa = (1. / dch_data->Lhalf) * tan(dphi / 2); - - //--- calculating wire position - // the points p1 and p2 correspond to the ends of the wire - - // point 1 - // double x1 = rz0; // m - // double y1 = 0.; // m - // double z1 = 0.; // m - double x1 = rz0; // m - double y1 = -stereosign * rz0 * kappa * dch_data->Lhalf; // m - double z1 = -dch_data->Lhalf; // m - - TVector3 p1(x1, y1, z1); - - // point 2 - double x2 = rz0; // m - double y2 = stereosign * rz0 * kappa * dch_data->Lhalf; // m - double z2 = dch_data->Lhalf; // m - - TVector3 p2(x2, y2, z2); - - // calculate phi rotation of whole twisted tube, ie, rotation at z=0 - double phi_z0 = Calculate_wire_phi_z0(ilayer, nphi); - p1.RotateZ(phi_z0); - p2.RotateZ(phi_z0); - //--- end calculating wire position - - return (p2 - p1).Unit(); -} - -TVector3 DCHdigi_v01::Calculate_wire_z0_point(int ilayer, int nphi) const { - auto& l = this->dch_data->database.at(ilayer); - double rz0 = l.radius_sw_z0; - TVector3 p1(rz0, 0, 0); - double phi_z0 = Calculate_wire_phi_z0(ilayer, nphi); - p1.RotateZ(phi_z0); - return p1; -} - -// calculate phi rotation of whole twisted tube, ie, rotation at z=0 -double DCHdigi_v01::Calculate_wire_phi_z0(int ilayer, int nphi) const { - auto& l = this->dch_data->database.at(ilayer); - int ncells = l.nwires / 2; - double phistep = TMath::TwoPi() / ncells; - double phi_z0 = (nphi + 0.25 * (l.layer % 2)) * phistep; - return phi_z0; -} - -/////////////////////////////////////////////////////////////////////////////////////// -/////////////////////// Calculate vector from hit position to wire ///////////////// -/////////////////////////////////////////////////////////////////////////////////////// -TVector3 DCHdigi_v01::Calculate_hitpos_to_wire_vector(int ilayer, int nphi, const TVector3& hit_position /*in cm*/) const { - // Solution distance from a point to a line given here: - // https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line#Vector_formulation - TVector3 n = this->Calculate_wire_vector_ez(ilayer, nphi); - TVector3 a = this->Calculate_wire_z0_point(ilayer, nphi); - // Remember using cm as natural units of DD4hep consistently! - // TVector3 p {hit_position.x()*MM_TO_CM,hit_position.y()*MM_TO_CM,hit_position.z()*MM_TO_CM}; - - TVector3 a_minus_p = a - hit_position; - double a_minus_p_dot_n = a_minus_p.Dot(n); - TVector3 scaled_n = a_minus_p_dot_n * n; - //hit_to_wire_vector = a_minus_p - scaled_n; - return (a_minus_p - scaled_n); -} /////////////////////////////////////////////////////////////////////////////////////// /////////////////////// CalculateNClusters //////////////////////////////// From 2564163dfe9918e58eaf4cd46863b89981288bd7 Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Fri, 22 Nov 2024 15:58:05 +0100 Subject: [PATCH 50/56] use new geometry functions from data extension, safer way of saving output histograms --- DCHdigi/include/DCHdigi_v01.h | 8 ++++++- DCHdigi/src/DCHdigi_v01.cpp | 39 +++++++++++++++++++++++++++++------ 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/DCHdigi/include/DCHdigi_v01.h b/DCHdigi/include/DCHdigi_v01.h index 81bb291..21a9401 100644 --- a/DCHdigi/include/DCHdigi_v01.h +++ b/DCHdigi/include/DCHdigi_v01.h @@ -72,7 +72,6 @@ #include "AlgData.h" /// constant to convert from mm (EDM4hep) to DD4hep (cm) -constexpr double MM_TO_CM = 0.1; struct DCHdigi_v01 final : k4FWCore::MultiTransformer< @@ -87,6 +86,9 @@ struct DCHdigi_v01 final operator()(const edm4hep::SimTrackerHitCollection&, const edm4hep::EventHeaderCollection&) const override; private: + /// conversion factor mm to cm, static to the class to avoid clash with DD4hep + static constexpr double MM_TO_CM = 0.1; + //------------------------------------------------------------------ // machinery for geometry @@ -193,6 +195,10 @@ struct DCHdigi_v01 final /// histogram to store smearing perpendicular the wire TH1D* hSxy; + + /// Create ROOT file for debug histograms + /// Does not change ROOT directory + void Create_outputROOTfile_for_debugHistograms(); }; DECLARE_COMPONENT(DCHdigi_v01); diff --git a/DCHdigi/src/DCHdigi_v01.cpp b/DCHdigi/src/DCHdigi_v01.cpp index ab53870..6b61090 100644 --- a/DCHdigi/src/DCHdigi_v01.cpp +++ b/DCHdigi/src/DCHdigi_v01.cpp @@ -50,6 +50,8 @@ StatusCode DCHdigi_v01::initialize() { /////////////////////////// retrieve data extension ////////////////////////// /////////////////////////////////////////////////////////////////////////////////// this->dch_data = DCH_DE.extension(); + if (not dch_data->IsValid()) + ThrowException("No valid data extension was found for detector <<" + DCH_name + ">>."); /////////////////////////////////////////////////////////////////////////////////// @@ -115,13 +117,13 @@ DCHdigi_v01::operator()(const edm4hep::SimTrackerHitCollection& input_sim_hits, // ------------------------------------------------------------------------- // calculate hit position projection into the wire - TVector3 hit_to_wire_vector = this->Calculate_hitpos_to_wire_vector(ilayer, nphi, hit_position); + TVector3 hit_to_wire_vector = this->dch_data->Calculate_hitpos_to_wire_vector(ilayer, nphi, hit_position); TVector3 hit_projection_on_the_wire = hit_position + hit_to_wire_vector; if (m_create_debug_histos.value()) { double distance_hit_wire = hit_to_wire_vector.Mag(); hDpw->Fill(distance_hit_wire); } - TVector3 wire_direction_ez = this->Calculate_wire_vector_ez(ilayer, nphi); + TVector3 wire_direction_ez = this->dch_data->Calculate_wire_vector_ez(ilayer, nphi); // ------------------------------------------------------------------------- // smear the position @@ -134,7 +136,7 @@ DCHdigi_v01::operator()(const edm4hep::SimTrackerHitCollection& input_sim_hits, hit_projection_on_the_wire += smearing_z * (wire_direction_ez.Unit()); if (m_create_debug_histos.value()) { // the distance from the hit projection and the wire should be zero - TVector3 dummy_vector = this->Calculate_hitpos_to_wire_vector(ilayer, nphi, hit_projection_on_the_wire); + TVector3 dummy_vector = this->dch_data->Calculate_hitpos_to_wire_vector(ilayer, nphi, hit_projection_on_the_wire); hDww->Fill(dummy_vector.Mag()); } @@ -193,9 +195,22 @@ DCHdigi_v01::operator()(const edm4hep::SimTrackerHitCollection& input_sim_hits, /////////////////////////////////////////////////////////////////////////////////////// /////////////////////// finalize ////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// -StatusCode DCHdigi_v01::finalize() { - if (m_create_debug_histos.value()) { - std::unique_ptr ofile{TFile::Open(m_out_debug_filename.value().c_str(), "recreate")}; + +void DCHdigi_v01::Create_outputROOTfile_for_debugHistograms() +{ + // save current ROOT directory + TDirectory* currentDir = gDirectory; + + // save the debug histograms in a file + // file is saved and closed when going out of scope + { + auto filename = m_out_debug_filename.value().c_str(); + std::unique_ptr ofile{TFile::Open( filename, "recreate")}; + if (!ofile || ofile->IsZombie()) + { + error() << "Error: Could not open file " << filename << std::endl; + return; + } ofile->cd(); hDpw->Write(); hDww->Write(); @@ -203,6 +218,18 @@ StatusCode DCHdigi_v01::finalize() { hSz->Write(); } + // Restore previous ROOT directory + if(currentDir && ( not currentDir->IsDestructed() ) ) + currentDir->cd(); + return; +} + +StatusCode DCHdigi_v01::finalize() { + if (m_create_debug_histos.value()) + { + this->Create_outputROOTfile_for_debugHistograms(); + } + return StatusCode::SUCCESS; } From d02cf89682699bb8bdd19d8c41c4da4f38e06558 Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Sun, 24 Nov 2024 19:00:34 +0100 Subject: [PATCH 51/56] update comments --- DCHdigi/README.md | 26 ++++++++++++-------------- DCHdigi/src/DCHdigi_v01.cpp | 2 +- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/DCHdigi/README.md b/DCHdigi/README.md index 2978f3a..c307fec 100644 --- a/DCHdigi/README.md +++ b/DCHdigi/README.md @@ -1,20 +1,18 @@ # Drift chamber (DCH) digitizers -## DCHsimpleDigitizer - -* Similar to DCHdigi_v01, but it uses the placement matrix of the wires to apply the smearing along/perpendicular to the sense wire -* No cluster counting information added into the digitized output -* It relies on a dedicated data extension, similar to DCHdigi_v01 +## DCHdigi_v01 -## DCHdigi description - -* Each simulated hit is transformed into a digitized hit -* The digitized hit position is the projection of the simulated hit position onto the sense wire (at the center of the cell) -* Smearing of the digitized hit position along the wire and radially is done according to the input parameter values (`zResolution_mm1` and `xyResolution_mm`, respectively) -* Number of clusters and their size is derived from file containing precalculated distributions, specified by the parameter `fileDataAlg`, and implemented as the option 3 described in F. Cuna et al, arXiv:2105.07064 -* Debug histograms are created if `create_debug_histograms` option is enabled (output file name can be given) -* Stand alone test run simulation of the drift chamber based on twisted tubes, and then apply the digitizer. Dedicated directory with all the files needed is given in `DCHdigi/test/test_DCHdigi/` +* Each simulated hit is transformed into a digitized hit. The digitized hit position is the projection of the simulated hit position onto the sense wire (at the center of the cell) +* Smearing of the digitized hit position along the wire and radially is done according to the input parameter values (`zResolution_mm` and `xyResolution_mm`, respectively) +* The digitized hit adds new information: number of clusters and their size, which are derived from precalculated distributions contained in an input file specified by the parameter `fileDataAlg`. The method and distributions corresponds to the option 3 described in F. Cuna et al, arXiv:2105.07064 * It requires that the cellID contain the layer and number of cell within the layer (nphi). It does not matter if the segmentation comes from geometrical segmentation by using twisted tubes and hyperboloids (and the cellID is created out of volume IDs), or the segmentation is virtual DD4hep segmentation * New digitized hit class is used as an EDM4hep data extension, to be integrated into EDM4hep +* Debug histograms are created if `create_debug_histograms` option is enabled (output file name can be given) +* Stand alone test run simulation of the drift chamber based on twisted tubes, and then apply the digitizer. Dedicated directory with all the files needed is given in `DCHdigi/test/test_DCHdigi/` * Random number generator uses the seeds calculated on an event basis by the UID service, from the podio header information (run/event number) -* At the moment, only one version: v01 + +## DCHsimpleDigitizer + +* Similar to DCHdigi_v01, but it uses the placement matrix of the wires to apply the smearing along/perpendicular to the sense wire +* No cluster counting information is added into the digitized output +* It relies on a dedicated data extension, similar to DCHdigi_v01 diff --git a/DCHdigi/src/DCHdigi_v01.cpp b/DCHdigi/src/DCHdigi_v01.cpp index 6b61090..dbcf7a9 100644 --- a/DCHdigi/src/DCHdigi_v01.cpp +++ b/DCHdigi/src/DCHdigi_v01.cpp @@ -7,7 +7,7 @@ #include "extension/MutableDriftChamberDigiV2.h" /////////////////////////////////////////////////////////////////////////////////////// -/////////////////////// DCHdigi constructor //////////////////////////// +////////////////////// DCHdigi_v01 constructor //////////////////////////// /////////////////////////////////////////////////////////////////////////////////////// // -- KeyValues("name of the variable that holds the name of the collection exposed in the python steering file", {"default name for the collection"}), DCHdigi_v01::DCHdigi_v01(const std::string& name, ISvcLocator* svcLoc) From 45d6c63d612ea030977ad7709ccff0affcc3d9fa Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Wed, 27 Nov 2024 11:12:43 +0100 Subject: [PATCH 52/56] update README --- DCHdigi/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/DCHdigi/README.md b/DCHdigi/README.md index c307fec..8102984 100644 --- a/DCHdigi/README.md +++ b/DCHdigi/README.md @@ -10,6 +10,7 @@ * Debug histograms are created if `create_debug_histograms` option is enabled (output file name can be given) * Stand alone test run simulation of the drift chamber based on twisted tubes, and then apply the digitizer. Dedicated directory with all the files needed is given in `DCHdigi/test/test_DCHdigi/` * Random number generator uses the seeds calculated on an event basis by the UID service, from the podio header information (run/event number) +* This digitizer is meant to be used with `DriftChamber_o1_v02` and is expected to work for the upcoming `DriftChamber_o1_v03` ## DCHsimpleDigitizer From b3886ce96760748ce74173938c61b85bb202e8a8 Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Wed, 27 Nov 2024 11:16:07 +0100 Subject: [PATCH 53/56] update README --- DCHdigi/README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/DCHdigi/README.md b/DCHdigi/README.md index 8102984..458f43e 100644 --- a/DCHdigi/README.md +++ b/DCHdigi/README.md @@ -10,10 +10,11 @@ * Debug histograms are created if `create_debug_histograms` option is enabled (output file name can be given) * Stand alone test run simulation of the drift chamber based on twisted tubes, and then apply the digitizer. Dedicated directory with all the files needed is given in `DCHdigi/test/test_DCHdigi/` * Random number generator uses the seeds calculated on an event basis by the UID service, from the podio header information (run/event number) -* This digitizer is meant to be used with `DriftChamber_o1_v02` and is expected to work for the upcoming `DriftChamber_o1_v03` +* This digitizer is meant to be used with `DriftChamber_o1_v02` from k4geo and is expected to work for the upcoming `DriftChamber_o1_v03` -## DCHsimpleDigitizer +## DCHsimpleDigitizerExtendedEdm -* Similar to DCHdigi_v01, but it uses the placement matrix of the wires to apply the smearing along/perpendicular to the sense wire +* Algorithm for creating digitized drift chamber hits (based on edm4hep::TrackerHit3D) from edm4hep::SimTrackerHit. Resolution along z and xy (distance to the wire) has to be specified. The smearing is applied in the wire reference frame, by means of the placement matrix of the wires * No cluster counting information is added into the digitized output * It relies on a dedicated data extension, similar to DCHdigi_v01 +* This digitizer is meant to be used with `DriftChamber_o1_v01` from k4geo. Deprecated. From 13ea3eb04ef032bf5f1f056bf3f77445df93f152 Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Wed, 27 Nov 2024 16:45:54 +0100 Subject: [PATCH 54/56] additional flag to make dNdx calculation optional, plus extra comments --- DCHdigi/include/DCHdigi_v01.h | 13 ++++++++++--- DCHdigi/src/DCHdigi_v01.cpp | 25 ++++++++++++++----------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/DCHdigi/include/DCHdigi_v01.h b/DCHdigi/include/DCHdigi_v01.h index 21a9401..19f2706 100644 --- a/DCHdigi/include/DCHdigi_v01.h +++ b/DCHdigi/include/DCHdigi_v01.h @@ -160,7 +160,11 @@ struct DCHdigi_v01 final //------------------------------------------------------------------ // cluster calculation, developed by Walaa - + + /// Flag to create to calculate cluster counting information + Gaudi::Property m_calculate_dndx{this, "calculate_dndx", false, + "Calculate number of clusters and electron per cluster"}; + /// file with distributions to be sampled Gaudi::Property m_fileDataAlg{ this, "fileDataAlg", "/eos/project/f/fccsw-web/www/filesForSimDigiReco/IDEA/DataAlgFORGEANT.root", @@ -174,6 +178,7 @@ struct DCHdigi_v01 final bool IsParticleCreatedInsideDriftChamber(const edm4hep::MCParticle &) const ; + //------------------------------------------------------------------ // debug information @@ -184,10 +189,12 @@ struct DCHdigi_v01 final /// name for the file that will contain the histograms for debugging Gaudi::Property m_out_debug_filename{this, "out_debug_filename", "dch_digi_alg_debug.root", "name for the file that will contain the histograms for debugging"}; - /// histogram to store distance from hit position to the wire + /// histogram to store distance from sim hit position to the sense wire TH1D* hDpw; - /// histogram to store distance from hit projection to the wire (should be zero) + /// histogram to store distance from digi-hit to the wire. Should be zero because digi-hit central position lies on the wire. + /// This histogram is a consistency check, because the function used to calculate the distance to the wire is different from + /// the function used to calculate the digi-hit central position from a sim-hit position TH1D* hDww; /// histogram to store smearing along the wire diff --git a/DCHdigi/src/DCHdigi_v01.cpp b/DCHdigi/src/DCHdigi_v01.cpp index dbcf7a9..a981046 100644 --- a/DCHdigi/src/DCHdigi_v01.cpp +++ b/DCHdigi/src/DCHdigi_v01.cpp @@ -81,9 +81,9 @@ StatusCode DCHdigi_v01::initialize() { PrintConfiguration(ss); info() << ss.str().c_str() << endmsg; if (m_create_debug_histos.value()) { - hDpw = new TH1D("hDpw", "Distance hit to the wire, in cm", 100, 0, 1); + hDpw = new TH1D("hDpw", "Distance from sim-hit to the wire, in cm", 100, 0, 1); hDpw->SetDirectory(0); - hDww = new TH1D("hDww", "Distance hit projection to the wire, in cm. Should be zero", 100, 0, 1); + hDww = new TH1D("hDww", "Distance from digi-hit to the wire, in cm. Should be zero because digi-hit central position lies on the wire", 100, 0, 1); hDww->SetDirectory(0); hSz = new TH1D("hSz", "Smearing along the wire, in cm", 100, 0, 5 * m_z_resolution.value()); hSz->SetDirectory(0); @@ -157,8 +157,6 @@ DCHdigi_v01::operator()(const edm4hep::SimTrackerHitCollection& input_sim_hits, auto directionSW = Convert_TVector3_to_EDM4hepVector(wire_direction_ez, 1. / MM_TO_CM); float distanceToWire = distanceToWire_smeared / MM_TO_CM; - auto [nCluster, nElectrons_v] = CalculateClusters(input_sim_hit); - extension::MutableDriftChamberDigiV2 oDCHdigihit; oDCHdigihit.setCellID(input_sim_hit.getCellID()); oDCHdigihit.setType(type); @@ -169,13 +167,18 @@ DCHdigi_v01::operator()(const edm4hep::SimTrackerHitCollection& input_sim_hits, oDCHdigihit.setPosition(positionSW); oDCHdigihit.setDirectionSW(directionSW); oDCHdigihit.setDistanceToWire(distanceToWire); - oDCHdigihit.setNCluster(nCluster); - // to return the total number of electrons within the step, do the following: - // int nElectronsTotal = std::accumulate( nElectrons_v.begin(), nElectrons_v.end(), 0); - // oDCHdigihit.setNElectronsTotal(nElectronsTotal); - // to copy the vector of each cluster size to the EDM4hep data extension, do the following: - for( auto ne : nElectrons_v ) - oDCHdigihit.addToNElectrons(ne); + // For the sake of speed, let the dNdx calculation be optional + if( m_calculate_dndx.value() ) + { + auto [nCluster, nElectrons_v] = CalculateClusters(input_sim_hit); + oDCHdigihit.setNCluster(nCluster); + // to return the total number of electrons within the step, do the following: + // int nElectronsTotal = std::accumulate( nElectrons_v.begin(), nElectrons_v.end(), 0); + // oDCHdigihit.setNElectronsTotal(nElectronsTotal); + // to copy the vector of each cluster size to the EDM4hep data extension, do the following: + for( auto ne : nElectrons_v ) + oDCHdigihit.addToNElectrons(ne); + } output_digi_hits.push_back(oDCHdigihit); From 2fbfc2b02027180ca9564320aa4a16a53851c256 Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Wed, 27 Nov 2024 16:48:55 +0100 Subject: [PATCH 55/56] update README and header doxygen --- DCHdigi/README.md | 2 +- DCHdigi/include/DCHdigi_v01.h | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/DCHdigi/README.md b/DCHdigi/README.md index 458f43e..e3faa87 100644 --- a/DCHdigi/README.md +++ b/DCHdigi/README.md @@ -4,7 +4,7 @@ * Each simulated hit is transformed into a digitized hit. The digitized hit position is the projection of the simulated hit position onto the sense wire (at the center of the cell) * Smearing of the digitized hit position along the wire and radially is done according to the input parameter values (`zResolution_mm` and `xyResolution_mm`, respectively) -* The digitized hit adds new information: number of clusters and their size, which are derived from precalculated distributions contained in an input file specified by the parameter `fileDataAlg`. The method and distributions corresponds to the option 3 described in F. Cuna et al, arXiv:2105.07064 +* The digitized hit adds dNdx information if flag `calculate_dndx` is enabled (default not). This information consist on number of clusters and their size, which are derived from precalculated distributions contained in an input file specified by the parameter `fileDataAlg`. The method and distributions corresponds to the option 3 described in F. Cuna et al, arXiv:2105.07064 * It requires that the cellID contain the layer and number of cell within the layer (nphi). It does not matter if the segmentation comes from geometrical segmentation by using twisted tubes and hyperboloids (and the cellID is created out of volume IDs), or the segmentation is virtual DD4hep segmentation * New digitized hit class is used as an EDM4hep data extension, to be integrated into EDM4hep * Debug histograms are created if `create_debug_histograms` option is enabled (output file name can be given) diff --git a/DCHdigi/include/DCHdigi_v01.h b/DCHdigi/include/DCHdigi_v01.h index 19f2706..b52bfb9 100644 --- a/DCHdigi/include/DCHdigi_v01.h +++ b/DCHdigi/include/DCHdigi_v01.h @@ -16,17 +16,19 @@ * (default name DCH_DigiCollection)
* @param DCH_name DCH subdetector name
* (default value DCH_v2)
- * @param fileDataAlg File needed for calculating cluster count and size
+ * @param calculate_dndx Optional flag to calcualte dNdx information
+ * (default value false)
+ * @param fileDataAlg File needed for calculating cluster count and size
* (default value /eos/.../DataAlgFORGEANT.root)
- * @param zResolution_mm Resolution (sigma for gaussian smearing) along the sense wire, in mm
+ * @param zResolution_mm Resolution (sigma for gaussian smearing) along the sense wire, in mm
* (default value 1 mm)
- * @param xyResolution_mm Resolution (sigma for gaussian smearing) perpendicular the sense wire, in mm
+ * @param xyResolution_mm Resolution (sigma for gaussian smearing) perpendicular the sense wire, in mm
* (default value 0.1 mm)
- * @param create_debug_histograms Optional flag to create debug histograms
+ * @param create_debug_histograms Optional flag to create debug histograms
* (default value false)
- * @param GeoSvcName Geometry service name
+ * @param GeoSvcName Geometry service name
* (default value GeoSvc)
- * @param uidSvcName The name of the UniqueIDGenSvc instance, used to create seed for each event/run, ensuring reproducibility.
+ * @param uidSvcName The name of the UniqueIDGenSvc instance, used to create seed for each event/run, ensuring reproducibility.
* (default value uidSvc)
*
*/ From 7e20301d304dc6b13a855a12b33377fb3c2b0384 Mon Sep 17 00:00:00 2001 From: Alvaro Tolosa Delgado Date: Wed, 27 Nov 2024 16:53:37 +0100 Subject: [PATCH 56/56] enable dNdx calculation in the test --- DCHdigi/test/test_DCHdigi/runDCHdigi.py | 1 + 1 file changed, 1 insertion(+) diff --git a/DCHdigi/test/test_DCHdigi/runDCHdigi.py b/DCHdigi/test/test_DCHdigi/runDCHdigi.py index 5d1939f..60ea103 100644 --- a/DCHdigi/test/test_DCHdigi/runDCHdigi.py +++ b/DCHdigi/test/test_DCHdigi/runDCHdigi.py @@ -21,6 +21,7 @@ DCHdigi.DCH_simhits=["DCHCollection"] DCHdigi.DCH_name="DCH_v2" DCHdigi.fileDataAlg="DataAlgFORGEANT.root" +DCHdigi.calculate_dndx=True DCHdigi.create_debug_histograms=True DCHdigi.zResolution_mm=1 DCHdigi.xyResolution_mm=0.1