From 9122c529b915eddd177aba83374d821a14b1f49f Mon Sep 17 00:00:00 2001 From: Fang Wenxing <wxfang@lxslc713.ihep.ac.cn> Date: Sun, 6 Sep 2020 18:02:52 +0800 Subject: [PATCH] add DCHDigi and DedxSvc --- Digitisers/DCHDigi/CMakeLists.txt | 25 +++++ Digitisers/DCHDigi/src/DCHDigiAlg.cpp | 114 ++++++++++++++++++++ Digitisers/DCHDigi/src/DCHDigiAlg.h | 56 ++++++++++ Examples/options/tut_detsim_dedx.py | 146 ++++++++++++++++++++++++++ Service/DedxSvc/CMakeLists.txt | 13 +++ Service/DedxSvc/DedxSvc/IDedxSvc.h | 18 ++++ Service/DedxSvc/src/DedxSvc.cpp | 45 ++++++++ Service/DedxSvc/src/DedxSvc.h | 34 ++++++ 8 files changed, 451 insertions(+) create mode 100644 Digitisers/DCHDigi/CMakeLists.txt create mode 100644 Digitisers/DCHDigi/src/DCHDigiAlg.cpp create mode 100644 Digitisers/DCHDigi/src/DCHDigiAlg.h create mode 100644 Examples/options/tut_detsim_dedx.py create mode 100644 Service/DedxSvc/CMakeLists.txt create mode 100644 Service/DedxSvc/DedxSvc/IDedxSvc.h create mode 100644 Service/DedxSvc/src/DedxSvc.cpp create mode 100644 Service/DedxSvc/src/DedxSvc.h diff --git a/Digitisers/DCHDigi/CMakeLists.txt b/Digitisers/DCHDigi/CMakeLists.txt new file mode 100644 index 00000000..33fa374e --- /dev/null +++ b/Digitisers/DCHDigi/CMakeLists.txt @@ -0,0 +1,25 @@ +gaudi_subdir(DCHDigi v0r0) + +find_package(DD4hep COMPONENTS DDG4 REQUIRED) +find_package(EDM4HEP REQUIRED ) +message("EDM4HEP_INCLUDE_DIRS: ${EDM4HEP_INCLUDE_DIR}") +message("EDM4HEP_LIB: ${EDM4HEP_LIBRARIES}") +include_directories(${EDM4HEP_INCLUDE_DIR}) + +find_package(CLHEP REQUIRED) +find_package(podio REQUIRED ) + +set(srcs + src/*.cpp +) + +gaudi_depends_on_subdirs( + Detector/DetInterface +) +## Modules +gaudi_add_module(DCHDigi ${srcs} + INCLUDE_DIRS FWCore GaudiKernel GaudiAlgLib CLHEP DD4hep + LINK_LIBRARIES FWCore GaudiKernel GaudiAlgLib CLHEP DD4hep ${DD4hep_COMPONENT_LIBRARIES} DDRec + -Wl,--no-as-needed + EDM4HEP::edm4hep EDM4HEP::edm4hepDict +) diff --git a/Digitisers/DCHDigi/src/DCHDigiAlg.cpp b/Digitisers/DCHDigi/src/DCHDigiAlg.cpp new file mode 100644 index 00000000..df87532e --- /dev/null +++ b/Digitisers/DCHDigi/src/DCHDigiAlg.cpp @@ -0,0 +1,114 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +#include "DCHDigiAlg.h" + + +#include "edm4hep/SimCalorimeterHit.h" +#include "edm4hep/CalorimeterHit.h" +#include "edm4hep/Vector3f.h" + +#include "DD4hep/Detector.h" +#include <DD4hep/Objects.h> + + +#include <math.h> +#include <cmath> +#include <algorithm> + +DECLARE_COMPONENT( DCHDigiAlg ) + +DCHDigiAlg::DCHDigiAlg(const std::string& name, ISvcLocator* svcLoc) + : GaudiAlgorithm(name, svcLoc), + _nEvt(0) +{ + + // Input collections + declareProperty("SimDCHitCollection", r_SimDCHCol, "Handle of the Input SimHit collection"); + + // Output collections + declareProperty("DigiDCHitCollection", w_DigiDCHCol, "Handle of Digi DCHit collection"); + + declareProperty("CaloAssociationCollection", w_AssociationCol, "Handle of Association collection"); + +} + +StatusCode DCHDigiAlg::initialize() +{ + /* + m_geosvc = service<IGeoSvc>("GeoSvc"); + if ( !m_geosvc ) throw "DCHDigiAlg :Failed to find GeoSvc ..."; + dd4hep::Detector* m_dd4hep = m_geosvc->lcdd(); + if ( !m_dd4hep ) throw "DCHDigiAlg :Failed to get dd4hep::Detector ..."; + m_cellIDConverter = new dd4hep::rec::CellIDPositionConverter(*m_dd4hep); + */ + std::cout<<"DCHDigiAlg::initialized"<< std::endl; + return GaudiAlgorithm::initialize(); +} + +StatusCode DCHDigiAlg::execute() +{ + std::map<unsigned long long, std::vector<edm4hep::SimTrackerHit> > id_hits_map; + edm4hep::TrackerHitCollection* Vec = w_DigiDCHCol.createAndPut(); + edm4hep::MCRecoTrackerAssociationCollection* AssoVec = w_AssociationCol.createAndPut(); + const edm4hep::SimTrackerHitCollection* SimHitCol = r_SimDCHCol.get(); + if(SimHitCol == 0) + { + std::cout<<"not found SimCalorimeterHitCollection"<< std::endl; + return StatusCode::SUCCESS; + } + std::cout<<"input sim hit size="<< SimHitCol->size() <<std::endl; + for( int i = 0; i < SimHitCol->size(); i++ ) + { + edm4hep::SimTrackerHit SimHit = SimHitCol->at(i); + unsigned long long id = SimHit.getCellID(); + + if ( id_hits_map.find(id) != id_hits_map.end()) id_hits_map[id].push_back(SimHit); + else + { + std::vector<edm4hep::SimTrackerHit> vhit; + vhit.push_back(SimHit); + id_hits_map[id] = vhit ; + } + } + + for(std::map<unsigned long long, std::vector<edm4hep::SimTrackerHit> >::iterator iter = id_hits_map.begin(); iter != id_hits_map.end(); iter++) + { + auto trkHit = Vec->create(); + trkHit.setCellID(iter->first); + double tot_edep = 0 ; + double tot_length = 0 ; + double tot_time = 0 ; + double tot_x = 0 ; + double tot_y = 0 ; + double tot_z = 0 ; + int simhit_size = iter->second.size(); + for(unsigned int i=0; i< simhit_size; i++) + { + tot_edep += iter->second.at(i).getEDep();//GeV + tot_length += iter->second.at(i).getPathLength();//mm + tot_time += iter->second.at(i).getTime(); + tot_x += iter->second.at(i).getPosition()[0]; + tot_y += iter->second.at(i).getPosition()[1]; + tot_z += iter->second.at(i).getPosition()[2]; + + auto asso = AssoVec->create(); + asso.setRec(trkHit); + asso.setSim(iter->second.at(i)); + asso.setWeight(1.0/simhit_size); + } + + trkHit.setTime(tot_time/simhit_size); + trkHit.setEDep(tot_edep/simhit_size); + trkHit.setEdx (tot_edep*1000/(tot_length/10) ); // MeV/cm + trkHit.setPosition (edm4hep::Vector3d(tot_x/simhit_size, tot_y/simhit_size, tot_z/simhit_size)); + } + std::cout<<"output digi DCHhit size="<< Vec->size() <<std::endl; + _nEvt ++ ; + + return StatusCode::SUCCESS; +} + +StatusCode DCHDigiAlg::finalize() +{ + info() << "Processed " << _nEvt << " events " << endmsg; + return GaudiAlgorithm::finalize(); +} diff --git a/Digitisers/DCHDigi/src/DCHDigiAlg.h b/Digitisers/DCHDigi/src/DCHDigiAlg.h new file mode 100644 index 00000000..e51c8c31 --- /dev/null +++ b/Digitisers/DCHDigi/src/DCHDigiAlg.h @@ -0,0 +1,56 @@ +#ifndef DCH_DIGI_ALG_H +#define DCH_DIGI_ALG_H + +#include "FWCore/DataHandle.h" +#include "GaudiAlg/GaudiAlgorithm.h" +#include "edm4hep/SimTrackerHitCollection.h" +#include "edm4hep/TrackerHitCollection.h" +#include "edm4hep/MCRecoTrackerAssociationCollection.h" + +#include <DDRec/DetectorData.h> +#include <DDRec/CellIDPositionConverter.h> +#include "DetInterface/IGeoSvc.h" + + + + +class DCHDigiAlg : public GaudiAlgorithm +{ + +public: + + DCHDigiAlg(const std::string& name, ISvcLocator* svcLoc); + + /** Called at the begin of the job before anything is read. + * Use to initialize the processor, e.g. book histograms. + */ + virtual StatusCode initialize() ; + + /** Called for every event - the working horse. + */ + virtual StatusCode execute() ; + + /** Called after data processing for clean up. + */ + virtual StatusCode finalize() ; + +protected: + + SmartIF<IGeoSvc> m_geosvc; + typedef std::vector<float> FloatVec; + int _nEvt ; + + //float m_length; + dd4hep::rec::CellIDPositionConverter* m_cellIDConverter; + + //Gaudi::Property<float> m_scale { this, "Scale", 1 }; + //Gaudi::Property<float> m_resolution{ this, "Res", 0.01 }; + + // Input collections + DataHandle<edm4hep::SimTrackerHitCollection> r_SimDCHCol{"DriftChamberHitsCollection", Gaudi::DataHandle::Reader, this}; + // Output collections + DataHandle<edm4hep::TrackerHitCollection> w_DigiDCHCol{"DigiDCHitsCollection", Gaudi::DataHandle::Writer, this}; + DataHandle<edm4hep::MCRecoTrackerAssociationCollection> w_AssociationCol{"DCHitAssociationCollection", Gaudi::DataHandle::Writer, this}; +}; + +#endif diff --git a/Examples/options/tut_detsim_dedx.py b/Examples/options/tut_detsim_dedx.py new file mode 100644 index 00000000..fa49a00e --- /dev/null +++ b/Examples/options/tut_detsim_dedx.py @@ -0,0 +1,146 @@ +#!/usr/bin/env python + +import os +print(os.environ["DD4HEP_LIBRARY_PATH"]) +import sys +# sys.exit(0) + +from Gaudi.Configuration import * + +############################################################################## +# Random Number Svc +############################################################################## +from Configurables import RndmGenSvc, HepRndm__Engine_CLHEP__RanluxEngine_ + +# rndmengine = HepRndm__Engine_CLHEP__RanluxEngine_() # The default engine in Gaudi +rndmengine = HepRndm__Engine_CLHEP__HepJamesRandom_() # The default engine in Geant4 +rndmengine.SetSingleton = True +rndmengine.Seeds = [42] + +# rndmgensvc = RndmGenSvc("RndmGenSvc") +# rndmgensvc.Engine = rndmengine.name() + + +############################################################################## +# Event Data Svc +############################################################################## +from Configurables import K4DataSvc +dsvc = K4DataSvc("EventDataSvc") + + +############################################################################## +# Geometry Svc +############################################################################## + +# geometry_option = "CepC_v4-onlyTracker.xml" +geometry_option = "CepC_v4-onlyVXD.xml" + +if not os.getenv("DETCEPCV4ROOT"): + print("Can't find the geometry. Please setup envvar DETCEPCV4ROOT." ) + sys.exit(-1) + +geometry_path = os.path.join(os.getenv("DETCEPCV4ROOT"), "compact", geometry_option) +if not os.path.exists(geometry_path): + print("Can't find the compact geometry file: %s"%geometry_path) + sys.exit(-1) +geometry_path = "/junofs/users/wxfang/MyGit/tmp/sdt/CEPCSW/Detector/DetDriftChamber/compact/det.xml" + +from Configurables import GeoSvc +geosvc = GeoSvc("GeoSvc") +geosvc.compact = geometry_path + +###### Dedx Svc ########################################################## +from Configurables import DedxSvc +dedxsvc = DedxSvc("DedxSvc") +dedxsvc.scale = 1 +dedxsvc.resolution = 0.01 +dedxsvc.material_Z = 26 +dedxsvc.material_A = 53.9396 +dedxsvc.material_density = 7.874 #g/cm^3 +############################################################################## +# Physics Generator +############################################################################## +from Configurables import GenAlgo +from Configurables import GtGunTool +from Configurables import StdHepRdr +from Configurables import SLCIORdr +from Configurables import HepMCRdr +from Configurables import GenPrinter + +gun = GtGunTool("GtGunTool") +gun.Particles = ["proton"] +gun.EnergyMins = [0.1] # GeV +gun.EnergyMaxs = [100] # GeV + +gun.ThetaMins = [90] # rad; 45deg +gun.ThetaMaxs = [90] # rad; 45deg + +gun.PhiMins = [0] # rad; 0deg +gun.PhiMaxs = [0] # rad; 360deg + +# stdheprdr = StdHepRdr("StdHepRdr") +# stdheprdr.Input = "/cefs/data/stdhep/CEPC250/2fermions/E250.Pbhabha.e0.p0.whizard195/bhabha.e0.p0.00001.stdhep" + +# lciordr = SLCIORdr("SLCIORdr") +# lciordr.Input = "/cefs/data/stdhep/lcio250/signal/Higgs/E250.Pbbh.whizard195/E250.Pbbh_X.e0.p0.whizard195/Pbbh_X.e0.p0.00001.slcio" + +# hepmcrdr = HepMCRdr("HepMCRdr") +# hepmcrdr.Input = "example_UsingIterators.txt" + +genprinter = GenPrinter("GenPrinter") + +genalg = GenAlgo("GenAlgo") +genalg.GenTools = ["GtGunTool"] +# genalg.GenTools = ["StdHepRdr"] +# genalg.GenTools = ["StdHepRdr", "GenPrinter"] +# genalg.GenTools = ["SLCIORdr", "GenPrinter"] +# genalg.GenTools = ["HepMCRdr", "GenPrinter"] + +############################################################################## +# Detector Simulation +############################################################################## +from Configurables import DetSimSvc + +detsimsvc = DetSimSvc("DetSimSvc") + +# from Configurables import ExampleAnaElemTool +# example_anatool = ExampleAnaElemTool("ExampleAnaElemTool") + +from Configurables import DetSimAlg + +detsimalg = DetSimAlg("DetSimAlg") + +# detsimalg.VisMacs = ["vis.mac"] + +detsimalg.RunCmds = [ +# "/tracking/verbose 1", +] +detsimalg.AnaElems = [ + # example_anatool.name() + # "ExampleAnaElemTool" + "Edm4hepWriterAnaElemTool" +] +detsimalg.RootDetElem = "WorldDetElemTool" + +from Configurables import AnExampleDetElemTool +example_dettool = AnExampleDetElemTool("AnExampleDetElemTool") + + +############################################################################## +# POD I/O +############################################################################## +from Configurables import PodioOutput +out = PodioOutput("outputalg") +out.filename = "test_detsim10.root" +out.outputCommands = ["keep *"] + +############################################################################## +# ApplicationMgr +############################################################################## + +from Configurables import ApplicationMgr +ApplicationMgr( TopAlg = [genalg, detsimalg, out], + EvtSel = 'NONE', + EvtMax = 10, + ExtSvc = [rndmengine, dsvc, geosvc], +) diff --git a/Service/DedxSvc/CMakeLists.txt b/Service/DedxSvc/CMakeLists.txt new file mode 100644 index 00000000..0fce402f --- /dev/null +++ b/Service/DedxSvc/CMakeLists.txt @@ -0,0 +1,13 @@ +gaudi_subdir(DedxSvc v0r0) + +set(DedxSvc_srcs + src/*.cpp +) +find_package(Geant4 REQUIRED ui_all vis_all) +include(${Geant4_USE_FILE}) +gaudi_install_headers(DedxSvc) + +gaudi_add_module(DedxSvc ${DedxSvc_srcs} + INCLUDE_DIRS GaudiKernel + LINK_LIBRARIES GaudiKernel +) diff --git a/Service/DedxSvc/DedxSvc/IDedxSvc.h b/Service/DedxSvc/DedxSvc/IDedxSvc.h new file mode 100644 index 00000000..14b76620 --- /dev/null +++ b/Service/DedxSvc/DedxSvc/IDedxSvc.h @@ -0,0 +1,18 @@ +#ifndef I_Dedx_SVC_H +#define I_Dedx_SVC_H + +#include "GaudiKernel/IService.h" + +#include "G4Step.hh" + +class IDedxSvc: virtual public IService { +public: + DeclareInterfaceID(IDedxSvc, 0, 1); // major/minor version + + virtual ~IDedxSvc() = default; + virtual float pred(const G4Step* aStep)=0 ; + +}; + + +#endif diff --git a/Service/DedxSvc/src/DedxSvc.cpp b/Service/DedxSvc/src/DedxSvc.cpp new file mode 100644 index 00000000..9a62508d --- /dev/null +++ b/Service/DedxSvc/src/DedxSvc.cpp @@ -0,0 +1,45 @@ +#include "DedxSvc.h" + +//https://folk.uib.no/ruv004/ +DECLARE_COMPONENT(DedxSvc) + +DedxSvc::DedxSvc(const std::string& name, ISvcLocator* svc) + : base_class(name, svc) +{ +} + +DedxSvc::~DedxSvc() +{ +} + +float DedxSvc::pred(const G4Step* aStep) +{ + G4Track* gTrack = aStep->GetTrack() ; + G4int z = gTrack->GetDefinition()->GetPDGCharge(); + if (z == 0) return 0; + G4double M = gTrack->GetDefinition()->GetPDGMass();//MeV + M = pow(10,6)*M; //to eV + G4double gammabeta=aStep->GetPreStepPoint()->GetBeta() * aStep->GetPreStepPoint()->GetGamma(); + if(gammabeta<0.01)return 0;//too low momentum + float beta = gammabeta/sqrt(1.0+pow(gammabeta,2)); + float gamma = gammabeta/beta; + float Tmax = 2*m_me*pow(gammabeta,2)/(1+(2*gamma*m_me/M)+pow(m_me/M,2)); + float dedx = m_K*pow(z,2)*m_material_Z*(0.5*log(2*m_me*pow(gammabeta,2)*Tmax/pow(m_I,2))-pow(beta,2))/(m_material_A*pow(beta,2)); + dedx = dedx*m_scale;// the material density can be absorbed in scale + dedx = dedx*(1+((*m_distribution)(m_generator))); + return dedx*m_material_density; // MeV / cm +} + +StatusCode DedxSvc::initialize() +{ + m_distribution = new std::normal_distribution<double>(0, m_resolution); + m_me = 0.511*pow(10,6);//0.511 MeV to eV + m_K = 0.307075;//const + m_I = m_material_Z*10; // Approximate + return StatusCode::SUCCESS; +} + +StatusCode DedxSvc::finalize() +{ + return StatusCode::SUCCESS; +} diff --git a/Service/DedxSvc/src/DedxSvc.h b/Service/DedxSvc/src/DedxSvc.h new file mode 100644 index 00000000..6f1f85eb --- /dev/null +++ b/Service/DedxSvc/src/DedxSvc.h @@ -0,0 +1,34 @@ +#ifndef Dedx_SVC_H +#define Dedx_SVC_H + +#include "DedxSvc/IDedxSvc.h" +#include <GaudiKernel/Service.h> +#include "G4Step.hh" +#include <random> + +class DedxSvc : public extends<Service, IDedxSvc> +{ + public: + DedxSvc(const std::string& name, ISvcLocator* svc); + ~DedxSvc(); + + + StatusCode initialize() override; + StatusCode finalize() override; + float pred(const G4Step* aStep) override; + + private: + + Gaudi::Property<float> m_material_Z{this, "material_Z", 2};//Default is Helium + Gaudi::Property<float> m_material_A{this, "material_A", 4}; + Gaudi::Property<float> m_material_density{this, "material_density", 0.000178};//g/cm^3 + Gaudi::Property<float> m_scale{this, "scale", 1}; + Gaudi::Property<float> m_resolution{this, "resolution", 0.01}; + float m_me;// Here me is the electron rest mass + float m_K; // K was set as a constant. + float m_I; // Mean excitation energy + std::default_random_engine m_generator; + std::normal_distribution<double>* m_distribution; +}; + +#endif -- GitLab