diff --git a/Digitisers/G2CDArbor/CMakeLists.txt b/Digitisers/G2CDArbor/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..8b35957aebdcf428770521dd13169739ae081115 --- /dev/null +++ b/Digitisers/G2CDArbor/CMakeLists.txt @@ -0,0 +1,27 @@ +gaudi_subdir(G2CDArbor v0r0) + +find_package(DD4hep COMPONENTS DDG4 REQUIRED) +find_package(EDM4HEP REQUIRED) +find_package(GEAR REQUIRED) +find_package(GSL REQUIRED ) +find_package(LCIO REQUIRED ) +find_package(podio REQUIRED ) +find_package(K4FWCore REQUIRED) + +message("EDM4HEP_INCLUDE_DIRS: ${EDM4HEP_INCLUDE_DIR}") +message("EDM4HEP_LIB: ${EDM4HEP_LIBRARIES}") +include_directories(${EDM4HEP_INCLUDE_DIR}) + +gaudi_depends_on_subdirs( + Service/GearSvc + Detector/DetInterface +) + +set(G2CDArbor_srcs src/*.cpp) + +# Modules +gaudi_add_module(G2CDArbor ${G2CDArbor_srcs} + INCLUDE_DIRS K4FWCore GaudiKernel GaudiAlgLib CLHEP DD4hep gear ${GSL_INCLUDE_DIRS} ${LCIO_INCLUDE_DIRS} + LINK_LIBRARIES K4FWCore GaudiKernel GaudiAlgLib CLHEP DD4hep ${GEAR_LIBRARIES} ${GSL_LIBRARIES} ${LCIO_LIBRARIES} + EDM4HEP::edm4hep EDM4HEP::edm4hepDict +) diff --git a/Digitisers/G2CDArbor/src/G2CDArborAlg.cpp b/Digitisers/G2CDArbor/src/G2CDArborAlg.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6e36e5ac7e44011caa8b3bdd5db6621ba783d3b2 --- /dev/null +++ b/Digitisers/G2CDArbor/src/G2CDArborAlg.cpp @@ -0,0 +1,1001 @@ +#include "G2CDArborAlg.h" + +#include "edm4hep/SimCalorimeterHit.h" +#include "edm4hep/CalorimeterHit.h" +#include "edm4hep/Vector3f.h" +#include "cellIDDecoder.h" + +#include "DD4hep/Detector.h" +#include "DD4hep/IDDescriptor.h" +#include "DD4hep/Plugins.h" + +// #include <EVENT/LCCollection.h> +// #include <EVENT/MCParticle.h> +// #include <EVENT/SimCalorimeterHit.h> +// #include <EVENT/CalorimeterHit.h> +// #include <EVENT/LCFloatVec.h> +// #include <EVENT/LCParameters.h> +// #include <IMPL/CalorimeterHitImpl.h> +// #include <IMPL/LCCollectionVec.h> +// #include <IMPL/LCFlagImpl.h> +// #include <IMPL/LCRelationImpl.h> +// #include "UTIL/CellIDDecoder.h" +// #include "DetectorPos.hh" + +#include <values.h> +#include <string> +#include <iostream> +#include <cmath> +#include <stdexcept> +#include <sstream> + +#include <TFile.h> +#include <TTree.h> +#include <Rtypes.h> +#include <TMath.h> +#include <TF1.h> +#include <TMath.h> +#include <TRandom.h> +#include <TVector3.h> + +using namespace std; +// using namespace lcio ; +// using namespace marlin ; + +DECLARE_COMPONENT( G2CDArborAlg ) + +// const double pi = acos(-1.0); + +struct DigiHit { + int digihitCellID0; + int digihitCellID1; + float digihitCharge; + float digihitEnergyDepo; + int digihitNum1mmCell; + float PosX; + float PosY; + float PosZ; + float LeadChargeDepo; + float ChargeShare; + edm4hep::SimCalorimeterHit * LeadSimCaloHit; +} ; + +//std::map <int, std::pair<float, float> >WeightVector; + +float ChanceOfKink = 0.1; +float KinkHitChargeBoost = 2.2; + +// G2CDArborAlg aG2CDArborAlg ; + +G2CDArborAlg::G2CDArborAlg(const std::string& name, ISvcLocator* svcLoc) + : GaudiAlgorithm(name, svcLoc), m_dd4hep_geo(nullptr), m_decoder(nullptr), + _output(0), m_pi(acos(-1.0)), _eventNr(0) +{ +// m_pi = acos(-1.0); + + // _description = "Gaseous Calorimeter Digitizer: take 1mm Simulated Hits as input"; + + // std::vector<std::string> ecalCollections; + // ecalCollections.push_back(std::string("EcalBarrelSiliconCollection")); + // ecalCollections.push_back(std::string("EcalEndcapSiliconCollection")); + // ecalCollections.push_back(std::string("EcalEndcapRingCollection")); + // registerInputCollections( LCIO::SIMCALORIMETERHIT, + // "ECALCollections" , + // "Input ECAL Hits Collection Names" , + // _ecalCollections , + // ecalCollections); + + // std::vector<std::string> outputEcalCollections; + // outputEcalCollections.push_back(std::string("ECALBarrel")); + // outputEcalCollections.push_back(std::string("ECALEndcap")); + // outputEcalCollections.push_back(std::string("ECALOther")); + // registerProcessorParameter("DigiECALCollection" , + // "Name of Digitized ECAL Hit Collections" , + // _outputEcalCollections, + // outputEcalCollections); + + // std::vector<std::string> EcalPreShowerCollections; + // EcalPreShowerCollections.push_back("EcalBarrelSiliconPreShowerCollection"); + // EcalPreShowerCollections.push_back("EcalEndcapRingPreShowerCollection"); + // EcalPreShowerCollections.push_back("EcalEndcapSiliconPreShowerCollection"); + // registerInputCollections( LCIO::CALORIMETERHIT, //adding a flag to Calo /SimCalo + // "HcalHitCollections" , + // "Hit Collection Names" , + // _EcalPreShowerCollections , + // EcalPreShowerCollections); + + // std::vector<float> calibrEcal; + // calibrEcal.push_back(40.91); + // calibrEcal.push_back(81.81); + // registerProcessorParameter("CalibrECAL" , + // "Calibration coefficients for ECAL" , + // _calibCoeffEcal, + // calibrEcal); + + // registerProcessorParameter("NumThinEcalLayer" , + // "Num of thiner Ecal layers" , + // _NEcalThinLayer, + // 20); + + // registerProcessorParameter("ECALThreshold" , + // "Threshold for ECAL Hits in GeV" , + // _thresholdEcal, + // (float)5.0e-5); + // registerProcessorParameter("HCALThreshold" , + // "Threshold for HCAL Hits in GeV" , + // _thresholdHcal, + // (float)0.11); + + + // std::vector<std::string> hcalCollections; + // hcalCollections.push_back(std::string("HcalBarrelRegCollection")); + // hcalCollections.push_back(std::string("HcalEndcapsCollection")); + // hcalCollections.push_back(std::string("HcalEndcapRingsCollection")); + // registerInputCollections( LCIO::SIMCALORIMETERHIT, + // "HCALCollections" , + // "HCAL Collection Names" , + // _hcalCollections , + // hcalCollections); + + // std::vector<std::string> outputHcalCollections; + // outputHcalCollections.push_back(std::string("HCALBarrel")); + // outputHcalCollections.push_back(std::string("HCALEndcap")); + // outputHcalCollections.push_back(std::string("HCALOther")); + // registerProcessorParameter("DigiHCALCollection" , + // "Name of Digitized HCAL Hit Collections" , + // _outputHcalCollections, + // outputHcalCollections); + + // std::vector<std::string> caloTruthLinkCollection; + // registerProcessorParameter("caloTruthLinkCollection", + // "caloTruthLinkCollection", + // _caloTruthLinkCollection, + // caloTruthLinkCollection); + + // std::vector<float> ChargeSpatialDistri; + // ChargeSpatialDistri.push_back(0.1); + // ChargeSpatialDistri.push_back(0.2); + // ChargeSpatialDistri.push_back(0.4); + // ChargeSpatialDistri.push_back(0.2); + // ChargeSpatialDistri.push_back(0.1); + // registerProcessorParameter("ChargeSpatialDistribution" , + // "Spactial Distribution of MIP charge X*Y;" , + // _ChargeSpatialDistri, + // ChargeSpatialDistri); + + // std::vector<float> ShowerPositionShiftID; + // ShowerPositionShiftID.push_back(0); + // ShowerPositionShiftID.push_back(0); + // ShowerPositionShiftID.push_back(0); + // registerProcessorParameter("PositionShiftID" , + // "Global Position Shift For Overlay" , + // _ShowerPositionShiftID, + // ShowerPositionShiftID); + + // registerProcessorParameter( "DigiCellSize" , + // "Size of Digitized Cell (in mm)" , + // _DigiCellSize , + // 10); + + // registerProcessorParameter( "ShiftInX" , + // "Shift Distance in X directoin (in mm) NP only" , + // _ShiftInX , + // float(0.0)); + + // registerProcessorParameter( "UsingDefaultDetector", + // "Flag Parameter Setting (0 ~ self definition, 1 ~ MircoMegas, 2 ~ GRPC_PS, 3 ~ GRPC_SPS)", + // _UsingDefaultDetector , + // 0); + + // registerProcessorParameter( "PolyaParaA" , + // "Polya: x^A*exp(-b*x) + c" , + // _PolyaParaA , + // float(0.7)); + + // registerProcessorParameter( "PolyaParaB" , + // "Polya: x^a*exp(-B*x) + c" , + // _PolyaParaB , + // float(0.045)); + + // registerProcessorParameter( "PolyaParaC" , + // "Polya: x^a*exp(-b*x) + C" , + // _PolyaParaC, + // float(0.03) ); + + // registerProcessorParameter( "ChanceOfKink" , + // "Chance of one boundary hit to create a multiple hit with boosted charge" , + // _ChanceOfKink, + // float(0.0) ); + + // registerProcessorParameter( "KinkHitChargeBoost" , + // "Scale factor of Charge on boosted multiple hits" , + // _KinkHitChargeBoost, + // float(1.0) ); + +} + +StatusCode G2CDArborAlg::initialize() { + m_geosvc = service<IGeoSvc>("GeoSvc"); + if (!m_geosvc) { + error() << "Failed to find GeoSvc." << endmsg; + return StatusCode::FAILURE; + } + m_dd4hep_geo = m_geosvc->lcdd(); + if (!m_dd4hep_geo) { + error() << "failed to retrieve dd4hep_geo: " << m_dd4hep_geo << endmsg; + return StatusCode::FAILURE; + } + + // get the DD4hep readout + const std::string name_readout = "EcalBarrelCollection"; + m_decoder = m_geosvc->getDecoder(name_readout); + if (!m_decoder) { + error() << "Failed to get the decoder. " << endmsg; + return StatusCode::FAILURE; + } + + m_encoder_str = "M:3,S-1:3,I:9,J:9,K-1:6"; + + // printParameters(); + // WeightVector.clear(); + + for (auto& ecal : m_ecalColNames) { + _ecalCollections.push_back( new SimCaloType(ecal, Gaudi::DataHandle::Reader, this) ); + } + + for (auto& ecalPreShower : m_ecalPreShowerColNames) { + _EcalPreShowerCollections.push_back( new SimCaloType(ecalPreShower, Gaudi::DataHandle::Reader, this) ); + } + + for (auto& hcal : m_hcalColNames) { + _hcalCollections.push_back( new SimCaloType(hcal, Gaudi::DataHandle::Reader, this) ); + } + + for (auto& ecalDigi : m_ecalOutputColNames) { + _outputEcalCollections.push_back( new CaloHitType(ecalDigi, Gaudi::DataHandle::Writer, this) ); + } + + for (auto& hcalDigi : m_hcalOutputColNames) { + _outputHcalCollections.push_back( new CaloHitType(hcalDigi, Gaudi::DataHandle::Writer, this) ); + } + + // for (auto& caloLink : m_caloTruthLinkColName) { + // _caloTruthLinkCollection.push_back( new McRecoCaloAssoType(caloLink, Gaudi::DataHandle::Writer, this) ); + // } + + for(unsigned int i=0; i<m_ChargeSpatialDistri.size(); i++){ + _ChargeSpatialDistri.push_back(m_ChargeSpatialDistri[i]); + } + + if( _outputHcalCollections.size() < _hcalCollections.size() ) + { + cout<<"WARNING! Output Collections Array Smaller than Input"<<endl; + exit(1); + } + else if( _ChargeSpatialDistri.size() % 2 == 0 ) + { + cout<<"WARNING! Better Organize Charge Spatial distribution array in odd integer length"<<endl; + cout << "_ChargeSpatialDistri.size = " << _ChargeSpatialDistri.size() << endl; + exit(2); + } + + if(_UsingDefaultDetector < 0 || _UsingDefaultDetector > 4) + { + cout<<"Parameter Flag Wrong. Need to be 0 (selfdefine), 1 (MircoMegas), 2 (GRPC_PS) or 3 (GRPC_SPS)"<<endl; + exit(0); + } + else if(_UsingDefaultDetector == 1) //MircoMegas Small Chamber, 2008 PS TB + { + _PolyaParaA = 0.7; + _PolyaParaB = 0.045; + _PolyaParaC = 0.03; + _ChargeSpatialDistri.clear(); + _ChargeSpatialDistri.push_back(0.1); + _ChargeSpatialDistri.push_back(8.0); + _ChargeSpatialDistri.push_back(0.1); + ChanceOfKink = 0.095; + KinkHitChargeBoost = 2.2; + } + else if(_UsingDefaultDetector == 2) //GRPC Cubic Meter, 2011 PS TB + { + _PolyaParaA = 4.0; + _PolyaParaB = 4.5; + _PolyaParaC = 0.0; + _ChargeSpatialDistri.clear(); + _ChargeSpatialDistri.push_back(0.1); + _ChargeSpatialDistri.push_back(0.1); + _ChargeSpatialDistri.push_back(0.1); + _ChargeSpatialDistri.push_back(0.1); + _ChargeSpatialDistri.push_back(0.1); + _ChargeSpatialDistri.push_back(0.1); + _ChargeSpatialDistri.push_back(0.1); + ChanceOfKink = 0.0; + KinkHitChargeBoost = 1.0; + } + else if(_UsingDefaultDetector == 3) //GRPC Bubic Meter, 2012 May SPS TB + { + _PolyaParaA = 1.1; + _PolyaParaB = 1.0; + _PolyaParaC = 0.0; + _ChargeSpatialDistri.clear(); + _ChargeSpatialDistri.push_back(0.1); + _ChargeSpatialDistri.push_back(0.2); + _ChargeSpatialDistri.push_back(0.3); + _ChargeSpatialDistri.push_back(0.6); + _ChargeSpatialDistri.push_back(0.6); + _ChargeSpatialDistri.push_back(0.6); + _ChargeSpatialDistri.push_back(0.3); + _ChargeSpatialDistri.push_back(0.2); + _ChargeSpatialDistri.push_back(0.1); + ChanceOfKink = 0.0; + KinkHitChargeBoost = 1.0; + } + else + { + ChanceOfKink = _ChanceOfKink; + KinkHitChargeBoost = _KinkHitChargeBoost; + } + + float PolyaDomain = 100; + if(_PolyaParaB ) + { + PolyaDomain = 20*_PolyaParaA/_PolyaParaB; + } + _QPolya = new TF1("QPolya", "x^[0]*exp(-1*x*[1]) + [2]", 0, PolyaDomain); + _QPolya->SetParameters(_PolyaParaA, _PolyaParaB, _PolyaParaC); + + cout<<"Parameters After Para Review: "<<ChanceOfKink<<", "<<KinkHitChargeBoost <<", "<<_DigiCellSize<<endl; + // printParameters(); + + int SizeCSD = _ChargeSpatialDistri.size(); + int CoverAreaLength = int((SizeCSD - 1)/2); + if(CoverAreaLength > _DigiCellSize - 1) + { + cout<<"WARNING! CoverAreaLength is too large comparing to the Digitized Cell Size: to have maximally 4 multiple hit, CoverAreaLength must <= _DigiCellSize - 1"<<endl; + exit(0); + } + int tmpIndex = 0; + float NormalWeightFactor = 0; + float NormalWeight[SizeCSD]; + int IndexA = 0; + int IndexB = 0; //Used to denote charge distributions... + float WeightA = 0; + float WeightB = 0; + + for( int i0 = 0; i0 < SizeCSD; i0++ ) + { + NormalWeightFactor += _ChargeSpatialDistri[i0]; + } + + for( int i1 = 0; i1 < SizeCSD; i1++ ) + { + NormalWeight[i1] = _ChargeSpatialDistri[i1]/NormalWeightFactor; + } + + int SignX(0); + int SignY(0); + pair<float, float> WMatrix; //if Vec(A) != Vec(B) + + for(int i2 = 0; i2 < _DigiCellSize; i2++) + { + for(int j2 = 0; j2 < _DigiCellSize; j2++) + { + tmpIndex = _DigiCellSize*i2 + j2; + IndexA = 0; + IndexB = 0; + WeightA = 0; + WeightB = 0; + + if( i2 < CoverAreaLength ) + { + IndexA = CoverAreaLength - i2; + SignX = -1; + } + else if( i2 > _DigiCellSize - CoverAreaLength - 1) + { + IndexA = CoverAreaLength + i2 - _DigiCellSize + 1; + SignX = 1; + } + + if( j2 < CoverAreaLength ) + { + IndexB = CoverAreaLength - j2; + SignY = -1; + } + else if( j2 > _DigiCellSize - CoverAreaLength - 1) + { + IndexB = CoverAreaLength + j2 - _DigiCellSize + 1; + SignY = 1; + } + + for(int i3 = 0; i3 < CoverAreaLength; i3 ++) + { + if(i3 < IndexA) WeightA += NormalWeight[i3]; + if(i3 < IndexB) WeightB += NormalWeight[i3]; + } + + WMatrix.first = SignX*WeightA; + WMatrix.second = SignY*WeightB; + WeightVector[tmpIndex] = WMatrix; + + cout<<WMatrix.first<<"/"<<WMatrix.second<<", "; + } + cout<<endl; + } + return GaudiAlgorithm::initialize(); +} + +StatusCode G2CDArborAlg::execute() +{ + // auto headers = m_headerCol.get(); + // auto header = headers->at(0); + // _eventNr = header.getEventNumber(); //to be solved + // _eventNr = evtP->getEventNumber(); + if(_eventNr % m_reportEvery == 0) cout<<"eventNr: "<<_eventNr<<endl; + _eventNr++; + + float HitEn = 0; + float DigiHitEn = 0; + int LayerNum = 0; + // TVector3 HitPos; //to be solved + int tmpM, tmpS, tmpI, tmpJ, tmpK; + int CurrI = 0; + int CurrJ = 0; + int DHIndexI = 0; + int DHIndexJ = 0; + float DHChargeWeight = 0; + int DHCellID0 = 0; + float RndCharge = 0; + int SingleMCPPID = 0; + //float SingleMCPPEn = 0; + float RefPosX = 0; + float RefPosY = 0; + float RefPosZ = 0; + float DeltaPosI = 0; + float DeltaPosJ = 0; + std::vector<float> CurrWeightVec; + float WeiI = 0; + float WeiJ = 0; + int DeltaI = 0; + int DeltaJ = 0; + int MapI = 0; + int MapJ = 0; + int MapIndex = 0; + float FHitPos[3] = {0, 0, 0}; + float currTime = 0; + float HitStepEn = 0; + float EmaxStep = 0; + + // LCCollectionVec *relcol = new LCCollectionVec(LCIO::LCRELATION); + // LCFlagImpl linkflag; + // linkflag.setBit(LCIO::CHBIT_LONG); + // relcol->setFlag(linkflag.getFlag()); + edm4hep::MCRecoCaloAssociationCollection* relcol = _caloTruthLinkCollection.createAndPut(); + + // LCCollection * MCPCol = evtP->getCollection("MCParticle"); + // for ( int s0(0); s0 < MCPCol->getNumberOfElements(); s0++) + // { + // MCParticle * a_MCP = dynamic_cast<MCParticle*> (MCPCol->getElementAt(s0)); + // if( a_MCP->getParents().size() == 0 ) + // { + // SingleMCPPID = a_MCP->getPDG(); + // //SingleMCPPEn = a_MCP->getEnergy(); + // break; + // } + // } + + // LCFlagImpl flag; + // flag.setBit(LCIO::CHBIT_LONG); //To set position & ID1 + // flag.setBit(LCIO::CHBIT_ID1); + // flag.setBit(LCIO::RCHBIT_ENERGY_ERROR); //In order to use an additional FLOAT + // flag.setBit(LCIO::RCHBIT_TIME); + + + double totalEnergy = 0.; + for (unsigned int k0 = 0; k0 < _ecalCollections.size(); ++k0) + { + // // try{ + // LCCollection *Ecalcol = evtP->getCollection( _ecalCollections[k0].c_str() ) ; + // CellIDDecoder<SimCalorimeterHit> idDecoder( Ecalcol ); + // int NumEcalhit = Ecalcol->getNumberOfElements(); + // LCCollectionVec *ecalcol = new LCCollectionVec(LCIO::CALORIMETERHIT); + // ecalcol->setFlag(flag.getFlag()); + // string EcalinitString = Ecalcol->getParameters().getStringVal(LCIO::CellIDEncoding); + // ecalcol->parameters().setValue(LCIO::CellIDEncoding, EcalinitString); + + // for(int k1 = 0; k1 < NumEcalhit; k1++) + // { + + edm4hep::CalorimeterHitCollection* ecalcol = _outputEcalCollections[k0]->createAndPut(); + auto Ecalcol = _ecalCollections[k0]->get(); + for (auto SimEcalhit: *Ecalcol){ + auto cellid = SimEcalhit.getCellID(); + // SimCalorimeterHit * SimEcalhit = dynamic_cast<SimCalorimeterHit*>( Ecalcol->getElementAt( k1 ) ) ; + // HitEn = SimEcalhit->getEnergy(); + // LayerNum = idDecoder(SimEcalhit)["K-1"]; + + // edm4hep::SimCalorimeterHit aa(SimEcalhit.getCellID(), SimEcalhit.getEnergy(), SimEcalhit.getPosition()); + ID_UTIL::CellIDDecoder<edm4hep::SimCalorimeterHit> cellIdDecoder(m_encoder_str); + const std::string layerCodingString(m_encoder_str); + const std::string layerCoding(this->GetLayerCoding(layerCodingString)); + if(m_readLCIO) LayerNum = m_decoder->get(cellid, "layer"); + else LayerNum = cellIdDecoder(&SimEcalhit)[layerCoding.c_str()]; + // cout << "LayerNum = " << LayerNum << endl; + + HitEn = SimEcalhit.getEnergy(); + unsigned long long cellID = SimEcalhit.getCellID(); + + currTime = 0; + EmaxStep = 0; + HitStepEn = 0; + // for(int k=0; k<SimEcalhit->getNMCContributions(); k++) + // { + for(int k=0; k<SimEcalhit.contributions_size(); k++){ + edm4hep::ConstCaloHitContribution hitContribution = SimEcalhit.getContributions(k); + // HitStepEn = SimEcalhit->getEnergyCont(k); + HitStepEn = hitContribution.getEnergy(); + if(HitStepEn > EmaxStep) + { + EmaxStep = HitStepEn; + // currTime = SimEcalhit->getTimeCont(k); + currTime = hitContribution.getTime(); + } + } + + // _calibCoeffEcal[0] = 48.16; + // _calibCoeffEcal[1] = 96.32; + if(LayerNum < _NEcalThinLayer) + DigiHitEn = HitEn * _calibCoeffEcal[0]; + else + DigiHitEn = HitEn * _calibCoeffEcal[1]; + + totalEnergy += DigiHitEn; + if(HitEn > _thresholdEcal) + { + // CalorimeterHitImpl * DigiEcalhit = new CalorimeterHitImpl(); + // FHitPos[0] = SimEcalhit->getPosition()[0] + _ShowerPositionShiftID[0]*10.0; + // FHitPos[1] = SimEcalhit->getPosition()[1] + _ShowerPositionShiftID[1]*10.0; + // FHitPos[2] = SimEcalhit->getPosition()[2] + _ShowerPositionShiftID[2]*10.0; + + edm4hep::Vector3f hitPos = SimEcalhit.getPosition(); + FHitPos[0] = hitPos.x + _ShowerPositionShiftID[0]*10.0; + FHitPos[1] = hitPos.y + _ShowerPositionShiftID[1]*10.0; + FHitPos[2] = hitPos.z + _ShowerPositionShiftID[2]*10.0; + edm4hep::Vector3f FHitPosition(FHitPos[0], FHitPos[1], FHitPos[2]); + + // DigiEcalhit->setTime(currTime); + // DigiEcalhit->setPosition( FHitPos ); + // DigiEcalhit->setCellID0(SimEcalhit->getCellID0()); + // DigiEcalhit->setCellID1(SimEcalhit->getCellID1()); + // DigiEcalhit->setEnergy(DigiHitEn); + // ecalcol->addElement(DigiEcalhit); + auto DigiEcalhit = ecalcol->create(); + DigiEcalhit.setTime(currTime); + DigiEcalhit.setPosition(FHitPosition); + DigiEcalhit.setCellID(cellID); + DigiEcalhit.setEnergy(DigiHitEn); + + // LCRelationImpl *rel = new LCRelationImpl(DigiEcalhit, SimEcalhit, 1.0); //only keep the leading contribution + // relcol->addElement(rel); + auto rel = relcol->create(); + rel.setRec(DigiEcalhit); + rel.setSim(SimEcalhit); + rel.setWeight(1.0); + } + } + + // evtP->addCollection(ecalcol,_outputEcalCollections[k0].c_str()); + + // // }catch(lcio::DataNotAvailableException zero) { } + } + // cout << "total energy after digiAlg: " << totalEnergy << endl; + + auto mcPart = r_mcParticle.get(); + // cout << "size of MCParticle: " << mcPart->size() << endl; + for(auto particle: *mcPart){ + double en = particle.getEnergy(); + // cout << "McParticle energy: " << en << " " << particle.parents_size() << endl; + } + + // string k = evtP->getDetectorName(); + + // if(k=="CEPC_v1" || k=="CEPC_v4" || k=="ild_o2_v05") // 1cm cell simulation... + // //if(k=="CEPC_v1" || k=="ild_o2_v05") // 1cm cell simulation... + // { + + // cout<<"Detector Tpype: "<<k<<endl; + + for (unsigned int k3 = 0; k3 < _hcalCollections.size(); ++k3) + { + // // try{ + // LCCollection *Hcalcol = evtP->getCollection( _hcalCollections[k3].c_str() ) ; + // int NumHcalhit = Hcalcol->getNumberOfElements(); + // LCCollectionVec *hcalcol = new LCCollectionVec(LCIO::CALORIMETERHIT); + // hcalcol->setFlag(flag.getFlag()); + // string HcalinitString = Hcalcol->getParameters().getStringVal(LCIO::CellIDEncoding); + // hcalcol->parameters().setValue(LCIO::CellIDEncoding, HcalinitString); + + // for(int k4 = 0; k4 < NumHcalhit; k4++) + // { + + edm4hep::CalorimeterHitCollection* hcalcol = _outputHcalCollections[k3]->createAndPut(); + auto Hcalcol = _hcalCollections[k3]->get(); + for(auto SimHcalhit: *Hcalcol){ + // SimCalorimeterHit * SimHcalhit = dynamic_cast<SimCalorimeterHit*>( Hcalcol->getElementAt( k4 ) ) ; + + cout<<"hcal"<<endl; + currTime = 0; + EmaxStep = 0; + HitStepEn = 0; + + // for(int k=0; k<SimHcalhit->getNMCContributions(); k++) + // { + for(int k=0; k<SimHcalhit.contributions_size(); k++){ + edm4hep::ConstCaloHitContribution hitContribution = SimHcalhit.getContributions(k); + + // HitStepEn = SimHcalhit->getEnergyCont(k); + HitStepEn = hitContribution.getEnergy(); + if(HitStepEn > EmaxStep) + { + EmaxStep = HitStepEn; + // currTime = SimHcalhit->getTimeCont(k); + currTime = hitContribution.getTime(); + } + } + + // if(SimHcalhit->getEnergy() > 0) //some threshold can be added. + if(SimHcalhit.getEnergy() > 0) //some threshold can be added. + { + // CalorimeterHitImpl * DigiHcalhit = new CalorimeterHitImpl(); + + // FHitPos[0] = SimHcalhit->getPosition()[0] + _ShowerPositionShiftID[0]*10.0; + // FHitPos[1] = SimHcalhit->getPosition()[1] + _ShowerPositionShiftID[1]*10.0; + // FHitPos[2] = SimHcalhit->getPosition()[2] + _ShowerPositionShiftID[2]*10.0; + + edm4hep::Vector3f hitPos = SimHcalhit.getPosition(); + FHitPos[0] = hitPos.x + _ShowerPositionShiftID[0]*10.0; + FHitPos[1] = hitPos.y + _ShowerPositionShiftID[1]*10.0; + FHitPos[2] = hitPos.z + _ShowerPositionShiftID[2]*10.0; + edm4hep::Vector3f FHitPosition(FHitPos[0], FHitPos[1], FHitPos[2]); + + // DigiHcalhit->setTime(currTime); + // DigiHcalhit->setPosition( FHitPos ); + // DigiHcalhit->setCellID0(SimHcalhit->getCellID0()); + // DigiHcalhit->setCellID1(SimHcalhit->getCellID1()); + // //DigiHcalhit->setEnergy(DHCALCalibrationConstant); + // DigiHcalhit->setEnergy(_thresholdHcal); + // hcalcol->addElement(DigiHcalhit); + auto DigiHcalhit = hcalcol->create(); + DigiHcalhit.setTime(currTime); + DigiHcalhit.setPosition(FHitPosition); + DigiHcalhit.setCellID(SimHcalhit.getCellID()); + DigiHcalhit.setEnergy(_thresholdHcal); + + // LCRelationImpl *rel = new LCRelationImpl(DigiHcalhit, SimHcalhit, 1.0); //only keep the leading contribution + // relcol->addElement(rel); + auto rel = relcol->create(); + rel.setRec(DigiHcalhit); + rel.setSim(SimHcalhit); + rel.setWeight(1.0); + } + } + + // evtP->addCollection(hcalcol,_outputHcalCollections[k3].c_str()); + + // }catch(lcio::DataNotAvailableException zero) { } + } + + // LCCollectionVec *ecalPScol = new LCCollectionVec(LCIO::CALORIMETERHIT); + // ecalPScol->setFlag(flag.getFlag()); + // string EcalPSinitString = "M:3,S-1:3,I:9,J:9,K-1:6"; + // ecalPScol->parameters().setValue(LCIO::CellIDEncoding, EcalPSinitString); + + // // parameter CellIDEncoding [string]: M:3,S-1:3,I:9,J:9,K-1:6, + + // for(unsigned int s0 = 0; s0 < _EcalPreShowerCollections.size(); s0++) //I think should digitize and give a very small energy; even a new collection called PS Hits + // { + // try + // { + // LCCollection * PSHitColl = evtP ->getCollection(_EcalPreShowerCollections[s0].c_str()); + // int NHitsCurrCol = PSHitColl->getNumberOfElements(); + // for(int s1 = 0; s1 < NHitsCurrCol; s1++) + // { + // SimCalorimeterHit * a_hit = dynamic_cast<SimCalorimeterHit*>(PSHitColl->getElementAt(s1)); + // currTime = 0; + // EmaxStep = 0; + // HitStepEn = 0; + + // for(int k=0; k<a_hit->getNMCContributions(); k++) + // { + // HitStepEn = a_hit->getEnergyCont(k); + // if(HitStepEn > EmaxStep) + // { + // EmaxStep = HitStepEn; + // currTime = a_hit->getTimeCont(k); + // } + // } + + // CalorimeterHitImpl * PShit = new CalorimeterHitImpl(); + + // FHitPos[0] = a_hit->getPosition()[0] + _ShowerPositionShiftID[0]*10.0; + // FHitPos[1] = a_hit->getPosition()[1] + _ShowerPositionShiftID[1]*10.0; + // FHitPos[2] = a_hit->getPosition()[2] + _ShowerPositionShiftID[2]*10.0; + + // PShit->setTime(currTime); + // PShit->setPosition( FHitPos ); + // PShit->setCellID0(a_hit->getCellID0()); + // PShit->setCellID1(a_hit->getCellID1()); + // PShit->setEnergy(a_hit->getEnergy()); + // ecalPScol->addElement(PShit); + // LCRelationImpl *rel = new LCRelationImpl(PShit, a_hit, 1.0); + // relcol->addElement(rel); + // } + // }catch(lcio::DataNotAvailableException zero){} + // } + + // //evtP->addCollection(ecalPScol, "ECALPSHitCollection"); + // } + // else + // { + // for (unsigned int i(0); i < _hcalCollections.size(); ++i) + // { //strictly follow barrel, endcap, ring order + + // std::map <int, DigiHit> IDtoDigiHit; + // IDtoDigiHit.clear(); + // std::map <int, TVector3> IDtoPos; + // IDtoPos.clear(); + // std::map <int, float> IDtoTime; + // IDtoTime.clear(); + + + // try{ + // LCCollection * col = evtP->getCollection( _hcalCollections[i].c_str() ) ; + + // int numOrihits = col->getNumberOfElements(); + // CellIDDecoder<SimCalorimeterHit> idDecoder(col); + // LCCollectionVec *hcalcol = new LCCollectionVec(LCIO::CALORIMETERHIT); + // string initString = "M:3,S-1:3,I:9,J:9,K-1:6"; //Need to verify + // hcalcol->parameters().setValue(LCIO::CellIDEncoding, initString); + // hcalcol->setFlag(flag.getFlag()); + + // for (int j(0); j < numOrihits; ++j) { + // SimCalorimeterHit * hit = dynamic_cast<SimCalorimeterHit*>( col->getElementAt( j ) ) ; + // HitEn = hit->getEnergy(); + + // currTime = 0; + // EmaxStep = 0; + // HitStepEn = 0; + + // for(int k=0; k<hit->getNMCContributions(); k++) + // { + // HitStepEn = hit->getEnergyCont(k); + // if(HitStepEn > EmaxStep) + // { + // EmaxStep = HitStepEn; + // currTime = hit->getTimeCont(k); + // } + // } + + + // tmpM = idDecoder(hit)["M"]; + // tmpS = idDecoder(hit)["S-1"]; + // tmpI = idDecoder(hit)["I"]; + // tmpJ = idDecoder(hit)["J"]; + // tmpK = idDecoder(hit)["K-1"]; + + // RefPosX = hit->getPosition()[0]; + // RefPosY = hit->getPosition()[1]; + // RefPosZ = hit->getPosition()[2]; + + // CurrI = tmpI/_DigiCellSize; + // CurrJ = tmpJ/_DigiCellSize; + // MapI = tmpI % _DigiCellSize; + // MapJ = tmpJ % _DigiCellSize; + // MapIndex = MapI * _DigiCellSize + MapJ; + // WeiI = WeightVector[MapIndex].first; + // WeiJ = WeightVector[MapIndex].second; + + // DeltaPosI = (float(_DigiCellSize) - 1.0)/2 - MapI; + // DeltaPosJ = (float(_DigiCellSize) - 1.0)/2 - MapJ; + + // // cout<<"DeltaI "<<DeltaPosI<<", "<<DeltaPosJ<<endl; + + // DeltaI = 0; + // DeltaJ = 0; + + // if(fabs(WeiI) > 1E-9) + // { + // DeltaI = ((WeiI > 0) ? 1: -1); + // } + // if(fabs(WeiJ) > 1E-9) + // { + // DeltaJ = ((WeiJ > 0) ? 1: -1); + // } + + // // cout<<"Weight... "<<WeiI<<"\t"<<DeltaI<<"\t"<<WeiJ<<"\t"<<DeltaJ<<endl; + + // RndCharge = _QPolya->GetRandom(); + + // CurrWeightVec.clear(); + // CurrWeightVec.push_back((1 - fabs(WeiI))*(1 - fabs(WeiJ))); + // if(DeltaI && !DeltaJ) + // { + // CurrWeightVec.push_back(fabs(WeiI)); + // } + // else if(DeltaJ && !DeltaI) + // { + // CurrWeightVec.push_back(fabs(WeiJ)); + // } + // else if(DeltaI && DeltaJ) + // { + // CurrWeightVec.push_back(fabs(WeiI) * (1 - fabs(WeiJ))); + // CurrWeightVec.push_back(fabs(WeiJ) * (1 - fabs(WeiI))); + // CurrWeightVec.push_back(fabs(WeiJ*WeiI)); + // } + + // for(int i0 = 0; i0 < int(CurrWeightVec.size()); i0++) + // { + // if(i0 == 0) + // { + // DHIndexI = CurrI; + // DHIndexJ = CurrJ; + // } + // else if(i0 == 1) + // { + // if(DeltaI) + // { + // DHIndexI = CurrI + DeltaI; + // DHIndexJ = CurrJ; + // } + // if(DeltaJ) + // { + // DHIndexI = CurrI; + // DHIndexJ = CurrJ + DeltaJ; + // } + // } + // else if(i0 == 2) + // { + // DHIndexI = CurrI + DeltaI; + // DHIndexJ = CurrJ; + // } + // else if(i0 == 3) + // { + // DHIndexI = CurrI + DeltaI; + // DHIndexJ = CurrJ + DeltaJ; + // } + + // DHChargeWeight = CurrWeightVec[i0]; + // DHCellID0 = (i<<30) + (tmpK<<24) + (DHIndexJ<<15) + (DHIndexI<<6) + (tmpS << 3) + tmpM; + + // if( IDtoDigiHit.find(DHCellID0) == IDtoDigiHit.end() && IDtoPos.find(DHCellID0) == IDtoPos.end() ) + // { + // IDtoDigiHit[DHCellID0].digihitCellID0 = DHCellID0; + // IDtoDigiHit[DHCellID0].digihitCharge = RndCharge * DHChargeWeight; + // IDtoDigiHit[DHCellID0].digihitEnergyDepo = HitEn * DHChargeWeight; //Assumption... + // IDtoDigiHit[DHCellID0].digihitNum1mmCell = 1; + // IDtoDigiHit[DHCellID0].LeadChargeDepo = RndCharge * DHChargeWeight; + // IDtoDigiHit[DHCellID0].LeadSimCaloHit = hit; + // IDtoDigiHit[DHCellID0].ChargeShare = DHChargeWeight; + + // if(i == 0) //Barrel + // { + // IDtoDigiHit[DHCellID0].PosX = RefPosX + (DeltaPosI + int(DHIndexI - CurrI)*_DigiCellSize) * cos(tmpS*pi/4.0) + _ShowerPositionShiftID[0]*_DigiCellSize; //(mm in unit) + // IDtoDigiHit[DHCellID0].PosY = RefPosY + (DeltaPosI + int(DHIndexI - CurrI)*_DigiCellSize)* sin(tmpS*pi/4.0) + _ShowerPositionShiftID[1]*_DigiCellSize; + // IDtoDigiHit[DHCellID0].PosZ = RefPosZ + DeltaPosJ + int(DHIndexJ - CurrJ)*_DigiCellSize + _ShowerPositionShiftID[2]*_DigiCellSize; //Rotation is needed, based on S; + // } + // else //endcap or ring; + // { + // IDtoDigiHit[DHCellID0].PosX = RefPosX + DeltaPosI + (DHIndexI - CurrI)*_DigiCellSize + _ShowerPositionShiftID[0]*_DigiCellSize; //(mm in unit) + // IDtoDigiHit[DHCellID0].PosY = RefPosY + DeltaPosJ + (DHIndexJ - CurrJ)*_DigiCellSize + _ShowerPositionShiftID[1]*_DigiCellSize; + // IDtoDigiHit[DHCellID0].PosZ = RefPosZ; + // } + + // HitPos.SetXYZ(IDtoDigiHit[DHCellID0].PosX, IDtoDigiHit[DHCellID0].PosY, IDtoDigiHit[DHCellID0].PosZ); + + // IDtoPos[DHCellID0] = HitPos; + // IDtoTime[DHCellID0] = currTime; + // } + // else + // { + // IDtoDigiHit[DHCellID0].digihitCharge += RndCharge * DHChargeWeight; + // IDtoDigiHit[DHCellID0].digihitEnergyDepo += HitEn * DHChargeWeight; + // IDtoDigiHit[DHCellID0].digihitNum1mmCell ++; + // if(RndCharge * DHChargeWeight > IDtoDigiHit[DHCellID0].LeadChargeDepo) + // { + // IDtoDigiHit[DHCellID0].LeadChargeDepo = RndCharge * DHChargeWeight; + // IDtoDigiHit[DHCellID0].LeadSimCaloHit = hit; + // IDtoDigiHit[DHCellID0].ChargeShare = DHChargeWeight; + // } + + // if(IDtoDigiHit[DHCellID0].PosX != IDtoPos[DHCellID0].X() ) + // cout<<"Position Changed.........."<<endl; + // } + + // //cout<<"Com "<<IDtoPos.size()<<"\t"<<IDtoDigiHit.size()<<endl; + // } + // } + + // float DigiHitPos[3]; + + // for(std::map <int, DigiHit>::iterator ff = IDtoDigiHit.begin(); ff!=IDtoDigiHit.end(); ff++) + // { + // CalorimeterHitImpl * calhit = new CalorimeterHitImpl(); + // LCRelationImpl *rel = new LCRelationImpl(calhit, ff->second.LeadSimCaloHit, ff->second.ChargeShare); //only keep the leading contribution + // relcol->addElement(rel); + + // calhit->setCellID0( ff->first ); //Assume 100% efficiency + // //calhit->setEnergy( DHCALCalibrationConstant ); //Charge + // calhit->setEnergy( _thresholdHcal ); //Charge + // calhit->setCellID1(SingleMCPPID); //Use ID1 & Energy Error to denote the MCP info... + // calhit->setEnergyError(ff->second.digihitCharge); // (SingleMCPPEn); + // /* + // DigiHitPos[0] = ff->second.PosX; + // DigiHitPos[1] = ff->second.PosY; + // DigiHitPos[2] = ff->second.PosZ; + // */ + // DigiHitPos[0] = IDtoPos[ff->first].X(); + // DigiHitPos[1] = IDtoPos[ff->first].Y(); + // DigiHitPos[2] = IDtoPos[ff->first].Z(); + + // calhit->setTime(IDtoTime[ff->first]); + // calhit->setPosition(DigiHitPos); + // hcalcol->addElement(calhit); + // } + + // evtP->addCollection(hcalcol,_outputHcalCollections[i].c_str()); + // IDtoDigiHit.clear(); + // } + // catch (lcio::DataNotAvailableException zero) { } + // } + + // } + + // evtP->addCollection(relcol, _caloTruthLinkCollection[0].c_str()); + return StatusCode::SUCCESS; +} + +StatusCode G2CDArborAlg::finalize() +{ + std::cout<<"General Gas Digitizer FINISHED"<<std::endl; + + for ( auto ecal : _ecalCollections ) { + delete ecal; + } + + for ( auto ecalPreShower : _EcalPreShowerCollections ) { + delete ecalPreShower; + } + + for ( auto hcal : _hcalCollections ) { + delete hcal; + } + + for ( auto ecalDigi : _outputEcalCollections ) { + delete ecalDigi; + } + + for ( auto hcalDigi : _outputHcalCollections ) { + delete hcalDigi; + } + + // for ( auto caloLink : _caloTruthLinkCollection ) { + // delete caloLink; + // } + + return GaudiAlgorithm::finalize(); +} + +std::string G2CDArborAlg::GetLayerCoding(const std::string &encodingString) const +{ + if (encodingString.find("layer") != std::string::npos) + return std::string("layer"); + + if (encodingString.find("K-1") != std::string::npos) + return std::string("K-1"); + + if (encodingString.find("K") != std::string::npos) + return std::string("K"); + + return std::string("unknown_layer_encoding"); +} + diff --git a/Digitisers/G2CDArbor/src/G2CDArborAlg.h b/Digitisers/G2CDArbor/src/G2CDArborAlg.h new file mode 100644 index 0000000000000000000000000000000000000000..9608419dcc74fddebe98d75d7c7d72f20044bba5 --- /dev/null +++ b/Digitisers/G2CDArbor/src/G2CDArborAlg.h @@ -0,0 +1,158 @@ +#ifndef G2CDARBORALG_H +#define G2CDARBORALG_H + +#include "FWCore/DataHandle.h" +#include "GaudiAlg/GaudiAlgorithm.h" +#include "GaudiKernel/Property.h" +#include "edm4hep/EventHeader.h" +#include "edm4hep/EventHeaderCollection.h" +#include "edm4hep/SimCalorimeterHitConst.h" +#include "edm4hep/SimCalorimeterHit.h" +#include "edm4hep/CalorimeterHit.h" +#include "edm4hep/CalorimeterHitCollection.h" +#include "edm4hep/SimCalorimeterHitCollection.h" +#include "edm4hep/MCRecoCaloAssociationCollection.h" +#include "edm4hep/MCParticleCollection.h" + +#include <DDRec/DetectorData.h> +#include <DDRec/CellIDPositionConverter.h> +#include "DetInterface/IGeoSvc.h" + +#include <string> +#include <iostream> +#include <fstream> + +#include <TObject.h> +#include <TNtuple.h> +#include <TTree.h> +#include <TFile.h> +#include <TF1.h> +#include <TH1F.h> +class TTree; + +class G2CDArborAlg : public GaudiAlgorithm +{ +public: + /* Processor* newProcessor() { return new G2CDArborAlg ; } */ + + G2CDArborAlg(const std::string& name, ISvcLocator* svcLoc); + /* G2CDArborAlg(); */ + /* ~G2CDArborAlg() {}; */ + + /** 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: + std::string GetLayerCoding(const std::string &encodingString) const; + + /* DataHandle<edm4hep::EventHeaderCollection> m_headerCol{"EventHeaderCol", Gaudi::DataHandle::Reader, this}; */ + + // Input collections + DataHandle<edm4hep::MCParticleCollection> r_mcParticle{"MCParticle", Gaudi::DataHandle::Reader, this}; + + typedef DataHandle<edm4hep::SimCalorimeterHitCollection> SimCaloType; + + Gaudi::Property<std::vector<std::string>> m_ecalColNames{this, "ECALCollections", {"EcalBarrelSiliconCollection", "EcalEndcapSiliconCollection", "EcalEndcapRingCollection"}, "Input ECAL Hits Collection Names"}; + std::vector<SimCaloType*> _ecalCollections; + + Gaudi::Property<std::vector<std::string>> m_ecalPreShowerColNames{this, "HcalHitCollections", {"EcalBarrelSiliconPreShowerCollection", "EcalEndcapRingPreShowerCollection", "EcalEndcapSiliconPreShowerCollection"}, "Hit Collection Names"}; + std::vector<SimCaloType*> _EcalPreShowerCollections; + + Gaudi::Property<std::vector<std::string>> m_hcalColNames{this, "HCALCollections", {"HcalBarrelRegCollection", "HcalEndcapsCollection", "HcalEndcapRingsCollection"}, "HCAL Collection Names"}; + std::vector<SimCaloType*> _hcalCollections; + + + // Output collections + typedef DataHandle<edm4hep::CalorimeterHitCollection> CaloHitType; + + Gaudi::Property<std::vector<std::string>> m_ecalOutputColNames{this, "DigiECALCollection", {"ECALBarrel", "ECALEndcap", "ECALOther"}, "Name of Digitized ECAL Hit Collections"}; + std::vector<CaloHitType*> _outputEcalCollections; + + Gaudi::Property<std::vector<std::string>> m_hcalOutputColNames{this, "DigiHCALCollection", {"HCALBarrel", "HCALEndcap", "HCALOther"}, "Name of Digitized HCAL Hit Collections"}; + std::vector<CaloHitType*> _outputHcalCollections; + + /* typedef DataHandle<edm4hep::MCRecoCaloAssociationCollection> McRecoCaloAssoType; */ + /* Gaudi::Property<std::vector<std::string>> m_caloTruthLinkColName{this, "caloTruthLinkCollection", {}, "caloTruthLinkCollection"}; */ + /* std::vector<McRecoCaloAssoType*> _caloTruthLinkCollection; */ + DataHandle<edm4hep::MCRecoCaloAssociationCollection> _caloTruthLinkCollection{"MCRecoCaloAssociationCollection", Gaudi::DataHandle::Writer, this}; + + mutable Gaudi::Property<std::vector<float>> m_ChargeSpatialDistri{this, "ChargeSpatialDistribution", {0.1, 0.2, 0.4, 0.2, 0.1}, "Spactial Distribution of MIP charge X*Y;"}; + mutable Gaudi::Property<std::vector<float>> _calibCoeffEcal{this, "CalibrECAL", {40.91, 81.81}, "Calibration coefficients for ECAL"}; + mutable Gaudi::Property<std::vector<float>> _ShowerPositionShiftID{this, "PositionShiftID", {0, 0, 0}, "Global Position Shift For Overlay"}; //should be of the form deltaI, J, K */ + + Gaudi::Property<bool> m_readLCIO{this, "ReadLCIO", false, "Read sim file with LCIO"}; + Gaudi::Property<int> m_reportEvery{this, "EventReportEvery", 100, "Event ID report every"}; + + Gaudi::Property<int> _NEcalThinLayer{this, "NumThinEcalLayer", 20, "Num of thiner Ecal layers"}; + Gaudi::Property<float> _thresholdEcal{this, "ECALThreshold", (float)5.0e-5, "Threshold for ECAL Hits in GeV"}; + Gaudi::Property<float> _thresholdHcal{this, "HCALThreshold", (float)0.11, "Threshold for HCAL Hits in GeV"}; + Gaudi::Property<int> _DigiCellSize{this, "DigiCellSize", 10, "Size of Digitized Cell (in mm)"}; + Gaudi::Property<float> _ShiftInX{this, "ShiftInX", (float)0.0, "Shift Distance in X directoin (in mm) NP only"}; + Gaudi::Property<int> _UsingDefaultDetector{this, "UsingDefaultDetector", 0, "Flag Parameter Setting (0 ~ self definition, 1 ~ MircoMegas, 2 ~ GRPC_PS, 3 ~ GRPC_SPS)"}; + Gaudi::Property<float> _PolyaParaA{this, "PolyaParaA", 0.7, "Polya: x^A*exp(-b*x) + c"}; + Gaudi::Property<float> _PolyaParaB{this, "PolyaParaB", 0.045, "Polya: x^a*exp(-B*x) + c"}; + Gaudi::Property<float> _PolyaParaC{this, "PolyaParaC", 0.03, "Polya: x^a*exp(-b*x) + C"}; + Gaudi::Property<float> _ChanceOfKink{this, "ChanceOfKink", 0.0, "Chance of one boundary hit to create a multiple hit with boosted charge"}; + Gaudi::Property<float> _KinkHitChargeBoost{this, "KinkHitChargeBoost", 1.0, "Scale factor of Charge on boosted multiple hits"}; + + /* std::string _treeFileName; */ + /* std::string _treeName; */ + /* std::string _colName; */ + /* std::vector<std::string> _caloTruthLinkCollection; */ + /* std::vector<std::string> _hcalCollections; */ + /* std::vector<std::string> _outputHcalCollections; */ + /* std::vector<std::string> _ecalCollections; */ + /* std::vector<std::string> _outputEcalCollections; */ + /* std::vector<std::string> _EcalPreShowerCollections; */ + std::vector<float> _ChargeSpatialDistri; + /* std::vector<float> _calibCoeffEcal; */ + /* std::vector<float> _ShowerPositionShiftID; //should be of the form deltaI, J, K */ + + std::map <int, std::pair<float, float> >WeightVector; + + const double m_pi; + + /* float _thresholdEcal; */ + /* float _thresholdHcal; */ + /* int _NEcalThinLayer; */ + int _overwrite; + /* int _DigiCellSize; */ + /* int _UsingDefaultDetector; */ + /* float _PolyaParaA, _PolyaParaB, _PolyaParaC; */ + /* float _ChanceOfKink, _KinkHitChargeBoost; */ + TTree *_outputTree; + TH1F *_NH1stLayer, *_NH8thLayer; + TF1 * _QPolya; + + int _Num; + int _eventNr; + + int _M, _S, _I, _J, _K, _Seg; + float _PosX, _PosY, _PosZ; + /* float _EDepo, _Charge, _ShiftInX; */ + int _NHit1mm, _NHit1mmCenter, _NHit1mmCorner, _NHit1mmSide; + int _TotalNHit1mm, _TotalNHit, _TotalMultiHit; + int _N1, _N2, _N3; + + std::string _fileName; + std::ostream *_output; + std::string m_encoder_str; + + SmartIF<IGeoSvc> m_geosvc; + dd4hep::Detector* m_dd4hep_geo; + dd4hep::DDSegmentation::BitFieldCoder* m_decoder; +}; + +#endif + + diff --git a/Digitisers/G2CDArbor/src/cellIDDecoder.h b/Digitisers/G2CDArbor/src/cellIDDecoder.h new file mode 100644 index 0000000000000000000000000000000000000000..6503f352d754fdac3279dab087abd6a359994145 --- /dev/null +++ b/Digitisers/G2CDArbor/src/cellIDDecoder.h @@ -0,0 +1,120 @@ +#ifndef cellIDDecoder_h +#define cellIDDecoder_h 1 + +#include "EVENT/LCCollection.h" +#include "UTIL/BitField64.h" +#include "lcio.h" +#include <string> + +// fixes problem in gcc 4.0.3 +#include "EVENT/LCParameters.h" + +//##################### changed for EMD4HEP ######## + +namespace ID_UTIL{ + + + /** Convenient class for decoding cellIDs from collection parameter LCIO::CellIDEncoding. + * See UTIL::BitField64 for a description of the encoding string. + * + * @see BitField64 + * @version $Id: CellIDDecoder.h,v 1.9.16.1 2011-03-04 14:09:07 engels Exp $ + */ + template <class T> + class CellIDDecoder { + + public: + + CellIDDecoder() = default ; + CellIDDecoder(const CellIDDecoder& ) = delete ; + CellIDDecoder& operator=(const CellIDDecoder& ) = delete ; + + + /** Constructor takes encoding string as argument. + */ + CellIDDecoder( const std::string& encoder_str ) : _oldHit(0) { + + if( encoder_str.length() == 0 ){ + throw( lcio::Exception( "CellIDDecoder : string of length zero provided as encoder string" ) ) ; + } + _b = new UTIL::BitField64( encoder_str ) ; + + } + + /** Constructor reads encoding string from collection parameter LCIO::CellIDEncoding. + */ + CellIDDecoder( const EVENT::LCCollection* col ) : _oldHit(0) { + + std::string initString("") ; + + if( col !=0 ) + initString = col->getParameters().getStringVal( lcio::LCIO::CellIDEncoding ) ; + + if( initString.size() == 0 ) { + + initString = _defaultEncoding ; + + std::cout << " ----------------------------------------- " << std::endl + << " WARNING: CellIDDecoder - no CellIDEncoding parameter in collection ! " + << std::endl + << " -> using default : \"" << initString << "\"" + << std::endl + << " ------------------------------------------ " + << std::endl ; + } + + _b = new UTIL::BitField64( initString ) ; + } + + ~CellIDDecoder(){ + + delete _b ; + } + + + /** Provides access to the bit fields, e.g. <br> + * int layer = myCellIDEncoding( hit )[ "layer" ] ; + * + */ + inline const UTIL::BitField64 & operator()( const T* hit ){ + + if( hit != _oldHit && hit ) { + auto id = hit->getCellID(); + unsigned int id0 = id&0xFFFFFFFF; + unsigned int id1 = id>>32; + //lcio::long64 val = lcio::long64( hit->getCellID0() & 0xffffffff ) | ( lcio::long64( hit->getCellID1() ) << 32 ) ; + lcio::long64 val = lcio::long64( id0 & 0xffffffff ) | ( lcio::long64( id1 ) << 32 ) ; + + _b->setValue( val ) ; + + _oldHit = hit ; + } + + return *_b ; + } + + + /** This can be used to set the default encoding that is used if no + * CellIDEncoding parameter is set in the collection, e.g. in older lcio files. + */ + static void setDefaultEncoding(const std::string& defaultEncoding ) { + + _defaultEncoding = std::string( defaultEncoding ) ; + } + + protected: + UTIL::BitField64* _b{} ; + const T* _oldHit{NULL} ; + + static std::string _defaultEncoding; + } ; + + template <class T> + std::string CellIDDecoder<T>::_defaultEncoding + = std::string("byte0:8,byte1:8,byte2:8,byte3:8,byte4:8,byte5:8,byte6:8,byte7:8") ; + + +} // namespace +#endif + + diff --git a/Examples/options/edm4hep_read.py b/Examples/options/edm4hep_read.py index fa8edc535d3e94e8e4b28105279fdcddb8e6f339..f401e38bad1abba484770f8c6c518d4cb74c41d1 100644 --- a/Examples/options/edm4hep_read.py +++ b/Examples/options/edm4hep_read.py @@ -3,7 +3,10 @@ from Gaudi.Configuration import * from Configurables import K4DataSvc -dsvc = K4DataSvc("EventDataSvc", input="test.root") +dsvc = K4DataSvc("EventDataSvc", + # input="test.root" + input="test-detsim10.root" +) from Configurables import PodioInput podioinput = PodioInput("PodioReader", collections=[