diff --git a/Detector/DetCRD/scripts/TDR_o1_v01/tracking.py b/Detector/DetCRD/scripts/TDR_o1_v01/tracking.py index 8c009a18e85f151bd272b67bdd1541badbbdc3c6..3f91a8f40c9e28a0a23b29ceec83d4c4c4da4272 100644 --- a/Detector/DetCRD/scripts/TDR_o1_v01/tracking.py +++ b/Detector/DetCRD/scripts/TDR_o1_v01/tracking.py @@ -54,7 +54,8 @@ podioinput = PodioInput("PodioReader", collections=[ # "SETCollection", "OTKBarrelCollection", "FTDCollection", - "MuonBarrelCollection" + "MuonBarrelCollection", + "MuonEndcapCollection" ]) @@ -156,7 +157,9 @@ digiTPC.TPCTrackerHitsCol = gashitname from Configurables import MuonDigiAlg digiMuon = MuonDigiAlg("MuonDigiAlg") digiMuon.MuonBarrelHitsCollection = "MuonBarrelCollection" +digiMuon.MuonEndcapHitsCollection = "MuonEndcapCollection" digiMuon.MuonBarrelTrackerHits = "MuonBarrelTrackerHits" +digiMuon.MuonEndcapTrackerHits = "MuonEndcapTrackerHits" digiMuon.WriteNtuple = 0 digiMuon.OutFileName = "Digi_MUON.root" ######################################### diff --git a/Digitization/DigiMuon/src/MuonDigiAlg.cpp b/Digitization/DigiMuon/src/MuonDigiAlg.cpp index 800b07625c80f9be59c96e1f94e309b7d506c3dc..347cb6c8c82d48cfb99437aec490509d1e36ad7d 100644 --- a/Digitization/DigiMuon/src/MuonDigiAlg.cpp +++ b/Digitization/DigiMuon/src/MuonDigiAlg.cpp @@ -42,9 +42,12 @@ MuonDigiAlg::MuonDigiAlg(const std::string& name, ISvcLocator* svcLoc) { // Input collections declareProperty("MuonBarrelHitsCollection", m_inputMuonBarrel, "Handle of the Input SimTrackerHit collection"); + declareProperty("MuonEndcapHitsCollection", m_inputMuonEndcap, "Handle of the Input SimTrackerHit collection"); + // Output collections declareProperty("MuonBarrelTrackerHits", m_outputMuonBarrel, "Handle of the output TrackerHit collection"); + declareProperty("MuonEndcapTrackerHits", m_outputMuonEndcap, "Handle of the output TrackerHit collection"); //declareProperty("MuonBarrelTrackerHitAssociationCollection", m_assMuonBarrel, "Handle of the Association collection between SimTrackerHit and TrackerHit"); } @@ -98,17 +101,26 @@ StatusCode MuonDigiAlg::initialize() error() << "Failed to get the Detector from GeomSvc" << endmsg; return StatusCode::FAILURE; } - std::string readout_name = m_inputMuonBarrel.objKey(); - debug() << "Readout name: " << readout_name << endmsg; m_cellIDConverter = new dd4hep::rec::CellIDPositionConverter(*m_dd4hep); - if(!m_cellIDConverter) { error() << "Failed to get the m_cellIDConverter." << endmsg; return StatusCode::FAILURE; } - m_decoder = m_geosvc->getDecoder(readout_name); - if(!m_decoder) + + std::string readout_name1 = m_inputMuonBarrel.objKey(); + debug() << "Readout name: " << readout_name1 << endmsg; + m_decoder1 = m_geosvc->getDecoder(readout_name1); + if(!m_decoder1) + { + error() << "Failed to get the decoder. " << endmsg; + return StatusCode::FAILURE; + } + + std::string readout_name2 = m_inputMuonEndcap.objKey(); + debug() << "Readout name: " << readout_name2 << endmsg; + m_decoder2 = m_geosvc->getDecoder(readout_name2); + if(!m_decoder2) { error() << "Failed to get the decoder. " << endmsg; return StatusCode::FAILURE; @@ -123,175 +135,452 @@ StatusCode MuonDigiAlg::initialize() StatusCode MuonDigiAlg::execute() { - - - Clear(); - trkhitVec = m_outputMuonBarrel.createAndPut(); - //auto assVec = m_assMuonBarrel.createAndPut(); - - const edm4hep::SimTrackerHitCollection* STHCol = nullptr; - try + for(int muonmode = 0; muonmode<2; muonmode++) { - STHCol = m_inputMuonBarrel.get(); - } - catch(GaudiException &e) - { - debug() << "Collection " << m_inputMuonBarrel.fullKey() << " is unavailable in event " << m_nEvt << endmsg; - return StatusCode::SUCCESS; - } - if(STHCol->size()==0) return StatusCode::SUCCESS; - debug() << m_inputMuonBarrel.fullKey() << " has SimTrackerHit "<< STHCol->size() << endmsg; - - - // number of strips parallel to beam direction - // in each slayer, each strip width=4cm, so - int strip_length[6] = {26, 38, 50, 62, 74, 86}; - - // define variables to be repeatedly used later - unsigned long long cellid; - double Edep, ADC, ADCmean; - int layer, slayer, strip, Fe, Env; - edm4hep::Vector3d pos; - dd4hep::Position ddpos; - // loop over all hits - for(auto simhit : *STHCol) - { - cellid = simhit.getCellID(); - Edep = simhit.getEDep();//GeV - layer = m_decoder->get(cellid, "Layer"); - slayer = m_decoder->get(cellid, "Superlayer"); - strip = m_decoder->get(cellid, "Stripe"); - Fe = m_decoder->get(cellid, "Fe"); - Env = m_decoder->get(cellid, "Env"); - pos = simhit.getPosition(); - - ddpos = m_cellIDConverter->position(cellid); - debug() << "Position:: " << ddpos.x() << " " << ddpos.y() << " " << ddpos.z() << endmsg; - - // if not satisfy energy requirement, skip this hit - //if ( Edep>0.01 || Edep<0.0001 ) continue; - - //calculate hit strip length - double hit_strip_length = std::sqrt((ddpos.x()-pos[0]*0.1)*(ddpos.x()-pos[0]*0.1)+(ddpos.y()-pos[1]*0.1)*(ddpos.y()-pos[1]*0.1)+(ddpos.z()-pos[2]*0.1)*(ddpos.z()-pos[2]*0.1)); - double hit_sipm_length; - - if(layer == 1) + if(muonmode == 0)//muon barrel run { - int tempnum = Env + slayer; - if(tempnum%2 == 0) + Clear(); + if(m_MuonMode == 2) continue; + trkhitVec = m_outputMuonBarrel.createAndPut(); + //auto assVec = m_assMuonBarrel.createAndPut(); + + const edm4hep::SimTrackerHitCollection* STHCol = nullptr; + try { - // 115 is the number of strips parpendicular - // to the beam axis in long-half-barrel - hit_sipm_length = (115 * 4.0)/2 - hit_strip_length; + STHCol = m_inputMuonBarrel.get(); } - else + catch(GaudiException &e) { - // 106 is the number of strips parpendicular - // to the beam axis in short-half-barrel - hit_sipm_length = (106 * 4.0)/2 - hit_strip_length; + debug() << "Collection " << m_inputMuonBarrel.fullKey() << " is unavailable in event " << m_nEvt << endmsg; + continue; } - } - if(layer == 2) - { + if(STHCol->size()==0) continue; + debug() << m_inputMuonBarrel.fullKey() << " has SimTrackerHit "<< STHCol->size() << endmsg; + // number of strips parallel to beam direction // in each slayer, each strip width=4cm, so - // the number * 4 cm gives the length of strips - // in each slayer parpendicular to the beam axis - hit_sipm_length = (strip_length[slayer-1] * 4)/2 - hit_strip_length; - } + int strip_length[6] = {26, 38, 50, 62, 74, 86}; + + // define variables to be repeatedly used later + std::array<unsigned long long, 2> key; + int pdgid; + unsigned long long cellid, abspdgid; + double Edep, ADC, ADCmean; + int layer, slayer, strip, Fe, Env; + edm4hep::Vector3d pos; + dd4hep::Position ddpos; + // loop over all hits + for(auto simhit : *STHCol) + { + auto mcp = simhit.getMCParticle(); + cellid = simhit.getCellID(); + pdgid = mcp.getPDG(); + abspdgid = std::abs(mcp.getPDG()); + key = std::array<unsigned long long, 2>{cellid, abspdgid}; + Edep = simhit.getEDep();//GeV + layer = m_decoder1->get(cellid, "Layer"); + slayer = m_decoder1->get(cellid, "Superlayer"); + strip = m_decoder1->get(cellid, "Stripe"); + Fe = m_decoder1->get(cellid, "Fe"); + Env = m_decoder1->get(cellid, "Env"); + pos = simhit.getPosition(); + ddpos = m_cellIDConverter->position(cellid); + debug() << "Position:: " << ddpos.x() << " " << ddpos.y() << " " << ddpos.z() << endmsg; + + // if not satisfy energy requirement, skip this hit + if ( Edep>0.1 || Edep<0.000001 ) continue; + + //calculate hit strip length + double hit_strip_length = std::sqrt((ddpos.x()-pos[0]*0.1)*(ddpos.x()-pos[0]*0.1)+(ddpos.y()-pos[1]*0.1)*(ddpos.y()-pos[1]*0.1)+(ddpos.z()-pos[2]*0.1)*(ddpos.z()-pos[2]*0.1)); + double hit_sipm_length; + + if(layer == 1) + { + int tempnum = Env + slayer; + if(tempnum%2 == 0) + { + // 115 is the number of strips parpendicular + // to the beam axis in long-half-barrel + hit_sipm_length = (115 * 4.0)/2 - hit_strip_length; + } + else + { + // 106 is the number of strips parpendicular + // to the beam axis in short-half-barrel + hit_sipm_length = (106 * 4.0)/2 - hit_strip_length; + } + } + if(layer == 2) + { + // number of strips parallel to beam direction + // in each slayer, each strip width=4cm, so + // the number * 4 cm gives the length of strips + // in each slayer parpendicular to the beam axis + hit_sipm_length = (strip_length[slayer-1] * 4)/2 - hit_strip_length; + } + + // digitize to ADC + ADCmean = 34*Edep*47.09/(23*0.00141);//mV + if(hit_sipm_length>10) + { + ADCmean = (16.0813*std::exp(-1*hit_sipm_length/50.8147)+19.5474)*Edep*47.09/(23*0.00141);//mV + } + ADC = rand_muon.Landau(ADCmean,7.922); + if(ADC<0) + { + ADC = 0; + } + + // fill the cell loop + map_cell_edep[key] += Edep; + map_cell_adc[key] += ADC; + map_cell_layer[key] = layer; + map_cell_slayer[key] = slayer; + map_cell_strip[key] = strip; + map_cell_fe[key] = Fe; + map_cell_env[key] = Env; + map_cell_pos[key] = pos; + map_cell_pdgid[key] = pdgid; + + // write to tree + if(_writeNtuple) + { + hit_cellid[n_hit] = cellid; + hit_posx[n_hit] = pos[0]; + hit_posy[n_hit] = pos[1]; + hit_posz[n_hit] = pos[2]; + hit_edep[n_hit] = Edep; + hit_layer[n_hit] = layer; + hit_slayer[n_hit] = slayer; + hit_strip[n_hit] = strip; + hit_fe[n_hit] = Fe; + hit_env[n_hit] = Env; + n_hit++; + } + + } + std::array<unsigned long long, 2> key1; + unsigned long long cellid1; + int layer1, slayer1, strip1, Fe1, Env1, pdgid1; + edm4hep::Vector3d pos1; + dd4hep::Position ddpos1; + + std::array<unsigned long long, 2> key2; + unsigned long long cellid2; + int layer2, slayer2, strip2, Fe2, Env2, pdgid2; + edm4hep::Vector3d pos2; + dd4hep::Position ddpos2; + + if(map_cell_edep.size()==0) continue; + //some criteria + for(const auto& item : map_cell_edep) + { + key = item.first; + if (map_cell_edep[key] < m_EdepMin || rand_muon.Uniform(0, 1)>m_hitEff || map_cell_adc[key] == 0) + { + map_cell_edep[key] = 0; + } + } - // digitize to ADC - ADCmean = 34*Edep*47.09/(23*0.00141);//mV - if(hit_sipm_length>10) - { - ADCmean = (16.0813*std::exp(-1*hit_sipm_length/50.8147)+19.5474)*Edep*47.09/(23*0.00141);//mV + double muonhitx, muonhity, muonhitz; + double Hit_max, Hit_min; + + // loop over all cells + for (const auto& item1 : map_cell_edep) + { + key1 = item1.first; + cellid1 = key1[0]; + Edep = map_cell_edep[key1]; + if ( Edep < 0.0001 ) continue; + int anotherlayer_cell_num = 0; + + ADC = map_cell_adc[key1]; + layer1 = map_cell_layer[key1]; + slayer1 = map_cell_slayer[key1]; + strip1 = map_cell_strip[key1]; + Fe1 = map_cell_fe[key1]; + Env1 = map_cell_env[key1]; + pos1 = map_cell_pos[key1]; + pdgid1 = map_cell_pdgid[key1]; + ddpos1 = m_cellIDConverter->position(cellid1); + + for (const auto& item2 : map_cell_edep) + { + key2 = item2.first; + cellid2 = key2[0]; + Edep = map_cell_edep[key2]; + if ( Edep < 0.0001 ) continue; + + layer2 = map_cell_layer[key2]; + slayer2 = map_cell_slayer[key2]; + strip2 = map_cell_strip[key2]; + Fe2 = map_cell_fe[key2]; + Env2 = map_cell_env[key2]; + pos2 = map_cell_pos[key2]; + pdgid2 = map_cell_pdgid[key2]; + ddpos2 = m_cellIDConverter->position(cellid2); + + if(slayer1!=slayer2 || Fe1!=Fe2 || Env1!=Env2 || layer1==layer2 || layer1==2) continue;//layer1 = 1 + Hit_min = pos1[2]*0.1-12; + Hit_max = pos1[2]*0.1+12; + if(ddpos2.z()<Hit_min || ddpos2.z()>Hit_max) continue; + anotherlayer_cell_num++; + map_muonhit[anotherlayer_cell_num] = ddpos2.z(); + map_pdgid[anotherlayer_cell_num] = -1; + if(std::abs(pos1[0]-pos2[0])>40 && std::abs(pos1[1]-pos2[1])>40 && std::abs(pos1[2]-pos2[2])>40) continue; + map_pdgid[anotherlayer_cell_num] = pdgid2; + } + + if(anotherlayer_cell_num == 0) continue; + if(anotherlayer_cell_num > 0) + { + for(int i=1; i<=anotherlayer_cell_num; i++) + { + muonhitx = ddpos1.x(); + muonhity = ddpos1.y(); + muonhitz = map_muonhit[i]; + // store to raw hit + edm4hep::MutableTrackerHit trkHit; + int true_pdgid = 0; + if(std::abs(pdgid1) == 13 && std::abs(map_pdgid[i]) == 13) + { + true_pdgid = 1;//pdgid->true muon hit + } + if(map_pdgid[i]==-1) + { + true_pdgid = 2;//ghost point + } + pos = edm4hep::Vector3d(muonhitx*10,muonhity*10,muonhitz*10);//mm + trkHit.setEDep(ADC); + trkHit.setQuality(true_pdgid); + trkHit.setCellID(cellid1); + trkHit.setPosition(pos); + trkhitVec->push_back( trkHit ); + } + } + // write for out ntuple + if(_writeNtuple) + { + cell_cellid[n_cell] = cellid; + cell_edep[n_cell] = Edep; + cell_adc[n_cell] = ADC; + cell_posx[n_cell] = pos[0]; + cell_posy[n_cell] = pos[1]; + cell_posz[n_cell] = pos[2]; + cell_layer[n_cell] = layer; + cell_slayer[n_cell] = slayer; + cell_strip[n_cell] = strip; + cell_fe[n_cell] = Fe; + cell_env[n_cell] = Env; + n_cell++; + } + } + if(_writeNtuple) + { + m_tree->Fill(); + } } - ADC = rand_muon.Landau(ADCmean,7.922); - if(ADC<0) + if(muonmode == 1)//muon endcap run { - ADC = 0; - } + Clear(); + if(m_MuonMode == 1) continue; + trkhitVec = m_outputMuonEndcap.createAndPut(); + const edm4hep::SimTrackerHitCollection* STHCol = nullptr; + try + { + STHCol = m_inputMuonEndcap.get(); + } + catch(GaudiException &e) + { + debug() << "Collection " << m_inputMuonEndcap.fullKey() << " is unavailable in event " << m_nEvt << endmsg; + continue; + } + if(STHCol->size()==0) continue; + debug() << m_inputMuonEndcap.fullKey() << " has SimTrackerHit "<< STHCol->size() << endmsg; + + double endcap_strip_length[193] = {2.12, 2.12, 2.12, 2.13, 2.14, 2.15, 2.16, 2.17, 2.19, 2.22, + 2.24, 2.28, 2.32, 2.37, 2.45, 2.65, 2.64, 2.63, 2.62, 2.61, + 2.60, 2.59, 2.57, 2.56, 2.54, 2.53, 2.51, 2.50, 2.48, 2.46, + 2.44, 2.42, 2.40, 2.38, 2.36, 2.33, 2.31, 2.28, 2.26, 2.23, + 2.20, 2.17, 2.14, 2.11, 2.07, 2.04, 2.00, 1.97, 1.93, 1.89, + 1.84, 1.80, 1.75, 1.70, 1.65, 1.60, 1.54, 1.48, 1.42, 1.35, + 1.28, 1.20, 1.12, 1.02, 0.92, 0.80, 0.65, 0.46, 2.20, 2.20, + 2.20, 2.20, 2.20, 2.20, 2.20, 2.21, 2.21, 2.21, 2.21, 2.22, + 2.22, 2.22, 2.23, 2.23, 2.23, 2.24, 2.24, 2.25, 2.25, 2.26, + 2.26, 2.27, 2.28, 2.28, 2.29, 2.30, 2.31, 2.32, 2.32, 2.33, + 2.34, 2.35, 2.36, 2.38, 2.39, 2.40, 2.41, 2.43, 2.44, 2.45, + 2.47, 2.49, 2.50, 2.52, 2.54, 2.56, 2.58, 2.60, 2.62, 2.65, + 2.67, 2.70, 2.73, 2.76, 2.79, 2.82, 2.86, 2.90, 2.94, 2.99, + 3.04, 3.10, 3.16, 3.23, 3.31, 3.41, 3.53, 3.70, 4.14, 4.12, + 4.09, 4.06, 4.03, 4.00, 3.97, 3.94, 3.91, 3.87, 3.84, 3.81, + 3.77, 3.74, 3.70, 3.67, 3.63, 3.59, 3.55, 3.51, 3.47, 3.43, + 3.38, 3.34, 3.30, 3.25, 3.20, 3.15, 3.10, 3.05, 3.00, 2.95, + 2.89, 2.83, 2.77, 2.71, 2.65, 2.58, 2.52, 2.45, 2.37, 2.30, + 2.22, 2.14, 2.05, 1.96, 1.86, 1.76, 1.65, 1.53, 1.40, 1.25, + 1.09, 0.89, 0.63}; + + + // define variables to be repeatedly used later + std::array<unsigned long long, 2> key; + int pdgid; + unsigned long long cellid, abspdgid; + double Edep, ADC, ADCmean; + int layer, slayer, strip, Env, Endcap; + edm4hep::Vector3d pos; + dd4hep::Position ddpos; + // loop over all hits + for(auto simhit : *STHCol) + { + auto mcp = simhit.getMCParticle(); + cellid = simhit.getCellID(); + pdgid = mcp.getPDG(); + abspdgid = std::abs(mcp.getPDG()); + key = std::array<unsigned long long, 2>{cellid, abspdgid}; + Edep = simhit.getEDep();//GeV + layer = m_decoder2->get(cellid, "Layer"); + slayer = m_decoder2->get(cellid, "Superlayer"); + strip = m_decoder2->get(cellid, "Stripe"); + Endcap = m_decoder2->get(cellid, "Endcap"); + Env = m_decoder2->get(cellid, "Env"); + pos = simhit.getPosition(); + ddpos = m_cellIDConverter->position(cellid); + debug() << "Position:: " << ddpos.x() << " " << ddpos.y() << " " << ddpos.z() << endmsg; + + // if not satisfy energy requirement, skip this hit + if ( Edep>0.1 || Edep<0.000001 ) continue; + + //calculate hit strip length + double hit_strip_length = std::sqrt((ddpos.x()-pos[0]*0.1)*(ddpos.x()-pos[0]*0.1)+(ddpos.y()-pos[1]*0.1)*(ddpos.y()-pos[1]*0.1)+(ddpos.z()-pos[2]*0.1)*(ddpos.z()-pos[2]*0.1)); + strip--; // strip id begin at 1 + double hit_sipm_length = endcap_strip_length[strip] * 0.5 * 100 - hit_strip_length;//cm + + // digitize to ADC + ADCmean = 34*Edep*47.09/(23*0.00141);//mV + if(hit_sipm_length>10) + { + ADCmean = (16.0813*std::exp(-1*hit_sipm_length/50.8147)+19.5474)*Edep*47.09/(23*0.00141);//mV + } + ADC = rand_muon.Landau(ADCmean,7.922); + if(ADC<0) + { + ADC = 0; + } + + map_cell_edep[key] += Edep; + map_cell_adc[key] += ADC; + map_cell_layer[key] = layer; + map_cell_slayer[key] = slayer; + map_cell_strip[key] = strip; + map_cell_fe[key] = Endcap; + map_cell_env[key] = Env; + map_cell_pos[key] = pos; + map_cell_pdgid[key] = pdgid; + } - // fill the cell loop - map_cell_edep[cellid] += Edep; - map_cell_adc[cellid] += ADC; - map_cell_layer[cellid] = layer; - map_cell_slayer[cellid] = slayer; - map_cell_strip[cellid] = strip; - map_cell_fe[cellid] = Fe; - map_cell_env[cellid] = Env; - - // write to tree - if(_writeNtuple) - { - hit_cellid[n_hit] = cellid; - hit_posx[n_hit] = pos[0]; - hit_posy[n_hit] = pos[1]; - hit_posz[n_hit] = pos[2]; - hit_edep[n_hit] = Edep; - hit_layer[n_hit] = layer; - hit_slayer[n_hit] = slayer; - hit_strip[n_hit] = strip; - hit_fe[n_hit] = Fe; - hit_env[n_hit] = Env; - n_hit++; - } - - } + std::array<unsigned long long, 2> key1; + unsigned long long cellid1; + int layer1, slayer1, strip1, Fe1, Env1, pdgid1; + edm4hep::Vector3d pos1; + dd4hep::Position ddpos1; - // loop over all cells - for (const auto& item : map_cell_edep) - { - cellid = item.first; - Edep = map_cell_edep[cellid]; - ADC = map_cell_adc[cellid]; - layer = map_cell_layer[cellid]; - slayer = map_cell_slayer[cellid]; - strip = map_cell_strip[cellid]; - Fe = map_cell_fe[cellid]; - Env = map_cell_env[cellid]; - - if ( Edep < 0.0005 ) continue; // skip cell energy < 50 MeV ?? Why? - //if ( Edep > 0.005 ) continue; // skip cell energy > 500 MeV ?? Why? - //if ( ADC > 10000 ) continue; // skip cell energy > 1000 ADC counts? why? - - // simulate hit efficiency: random > hiteff, skip the hit - if( rand_muon.Uniform(0, 1) > m_hitEff) continue; - - // store to raw hit - edm4hep::MutableTrackerHit trkHit; - ddpos = m_cellIDConverter->position(cellid); - pos = edm4hep::Vector3d(ddpos.x(),ddpos.y(),ddpos.z()); - trkHit.setEDep(ADC); - trkHit.setCellID(cellid); - trkHit.setPosition(pos); - trkhitVec->push_back( trkHit ); - - - // write for out ntuple - if(_writeNtuple) - { - cell_cellid[n_cell] = cellid; - cell_edep[n_cell] = Edep; - cell_adc[n_cell] = ADC; - cell_posx[n_cell] = pos[0]; - cell_posy[n_cell] = pos[1]; - cell_posz[n_cell] = pos[2]; - cell_layer[n_cell] = layer; - cell_slayer[n_cell] = slayer; - cell_strip[n_cell] = strip; - cell_fe[n_cell] = Fe; - cell_env[n_cell] = Env; - n_cell++; - } + std::array<unsigned long long, 2> key2; + unsigned long long cellid2; + int layer2, slayer2, strip2, Fe2, Env2, pdgid2; + edm4hep::Vector3d pos2; + dd4hep::Position ddpos2; - } + if(map_cell_edep.size()==0) continue; - if(_writeNtuple) - { - m_tree->Fill(); + for(const auto& item : map_cell_edep) + { + key = item.first; + if (map_cell_edep[key] < m_EdepMin || rand_muon.Uniform(0, 1)>m_hitEff || map_cell_adc[key] == 0) + { + map_cell_edep[key] = 0; + } + } + + double muonhitx, muonhity, muonhitz; + double Hit_max, Hit_min; + + // loop over all cells + for (const auto& item1 : map_cell_edep) + { + key1 = item1.first; + cellid1 = key1[0]; + Edep = map_cell_edep[key1]; + if ( Edep < 0.0001 ) continue; + int anotherlayer_cell_num = 0; + + ADC = map_cell_adc[key1]; + layer1 = map_cell_layer[key1]; + slayer1 = map_cell_slayer[key1]; + strip1 = map_cell_strip[key1]; + Fe1 = map_cell_fe[key1];//endcap + Env1 = map_cell_env[key1]; + pos1 = map_cell_pos[key1]; + pdgid1 = map_cell_pdgid[key1]; + ddpos1 = m_cellIDConverter->position(cellid1); + + for (const auto& item2 : map_cell_edep) + { + key2 = item2.first; + cellid2 = key2[0]; + Edep = map_cell_edep[key2]; + if ( Edep < 0.0001 ) continue; + + layer2 = map_cell_layer[key2]; + slayer2 = map_cell_slayer[key2]; + strip2 = map_cell_strip[key2]; + Fe2 = map_cell_fe[key2];//endcap + Env2 = map_cell_env[key2]; + pos2 = map_cell_pos[key2]; + pdgid2 = map_cell_pdgid[key2]; + ddpos2 = m_cellIDConverter->position(cellid2); + + if(Fe1!=Fe2 || slayer1!=slayer2 || layer1==layer2 || layer1==2) continue; + if(std::abs(Env2-Env1) == 2) continue; + Hit_min = pos1[0]*0.1-12; + Hit_max = pos1[0]*0.1+12; + if(ddpos2.x()<Hit_min || ddpos2.x()>Hit_max) continue; + anotherlayer_cell_num++; + map_muonhit[anotherlayer_cell_num] = ddpos2.x(); + map_pdgid[anotherlayer_cell_num] = -1; + if(std::abs(pos1[0]-pos2[0])>40 && std::abs(pos1[1]-pos2[1])>40 && std::abs(pos1[2]-pos2[2])>40) continue; + map_pdgid[anotherlayer_cell_num] = pdgid2; + } + if(anotherlayer_cell_num == 0) continue; + if(anotherlayer_cell_num > 0) + { + for(int i=1; i<=anotherlayer_cell_num; i++) + { + muonhitx = map_muonhit[i]; + muonhity = ddpos1.y(); + muonhitz = ddpos1.z(); + // store to raw hit + edm4hep::MutableTrackerHit trkHit; + int true_pdgid = 0; + if(std::abs(pdgid1) == 13 && std::abs(map_pdgid[i]) == 13) + { + true_pdgid = 1;//pdgid->true muon hit + } + if(map_pdgid[i]==-1) + { + true_pdgid = 2;//ghost point + } + pos = edm4hep::Vector3d(muonhitx*10,muonhity*10,muonhitz*10); + trkHit.setEDep(ADC); + trkHit.setQuality(true_pdgid); + trkHit.setCellID(cellid1); + trkHit.setPosition(pos); + trkhitVec->push_back( trkHit ); + } + } + } + } } + m_nEvt++; return StatusCode::SUCCESS; } @@ -321,5 +610,8 @@ void MuonDigiAlg::Clear() map_cell_strip.clear(); map_cell_fe.clear(); map_cell_env.clear(); - + map_cell_pos.clear(); + map_muonhit.clear(); + map_cell_pdgid.clear(); + map_pdgid.clear(); } diff --git a/Digitization/DigiMuon/src/MuonDigiAlg.h b/Digitization/DigiMuon/src/MuonDigiAlg.h index 93d6d21c9b1cfe46c046382fb671efd2999ba443..f5d0d412680e958cca69788dc9768121a943e45d 100644 --- a/Digitization/DigiMuon/src/MuonDigiAlg.h +++ b/Digitization/DigiMuon/src/MuonDigiAlg.h @@ -61,18 +61,22 @@ class MuonDigiAlg : public GaudiAlgorithm TFile* m_wfile; SmartIF<IGeomSvc> m_geosvc; - dd4hep::DDSegmentation::BitFieldCoder* m_decoder; + dd4hep::DDSegmentation::BitFieldCoder* m_decoder1; + dd4hep::DDSegmentation::BitFieldCoder* m_decoder2; dd4hep::rec::CellIDPositionConverter* m_cellIDConverter; dd4hep::Detector* m_dd4hep; - std::map<unsigned long long, double> map_cell_edep; - std::map<unsigned long long, double> map_cell_adc; - std::map<unsigned long long, int> map_cell_layer; - std::map<unsigned long long, int> map_cell_slayer; - std::map<unsigned long long, int> map_cell_strip; - std::map<unsigned long long, int> map_cell_fe; - std::map<unsigned long long, int> map_cell_env; - + std::map<std::array<unsigned long long, 2>, double> map_cell_edep; + std::map<std::array<unsigned long long, 2>, double> map_cell_adc; + std::map<std::array<unsigned long long, 2>, int> map_cell_layer; + std::map<std::array<unsigned long long, 2>, int> map_cell_slayer; + std::map<std::array<unsigned long long, 2>, int> map_cell_strip; + std::map<std::array<unsigned long long, 2>, int> map_cell_fe; + std::map<std::array<unsigned long long, 2>, int> map_cell_env; + std::map<std::array<unsigned long long, 2>, int> map_cell_pdgid; + std::map<std::array<unsigned long long, 2>, edm4hep::Vector3d> map_cell_pos; + std::map<int, double> map_muonhit; + std::map<int, int> map_pdgid; #define MAX_SIZE 10000 @@ -106,17 +110,21 @@ class MuonDigiAlg : public GaudiAlgorithm Gaudi::Property<int> _writeNtuple{this, "WriteNtuple", 1, "Write ntuple"}; Gaudi::Property<std::string> _filename{this, "OutFileName", "testout.root", "Output file name"}; - Gaudi::Property<double> m_hitEff{ this, "hitEff", 0.9, "Efficiency of a single hit on a Strip" }; + Gaudi::Property<double> m_MuonMode{ this, "MuonMode", 0, "Control the Muon section used in Digi" };// 1->Barrel; 2->Endcap; 0->Both; + Gaudi::Property<double> m_hitEff{ this, "SiPMEff", 0.95, "Efficiency of a single hit on a Strip" }; + Gaudi::Property<double> m_EdepMin{ this, "EdepMin", 0.0001, "Minimum Edep of a mip" }; // Input collections DataHandle<edm4hep::SimTrackerHitCollection> m_inputMuonBarrel{"MuonBarrelHitsCollection", Gaudi::DataHandle::Reader, this}; + DataHandle<edm4hep::SimTrackerHitCollection> m_inputMuonEndcap{"MuonEndcapHitsCollection", Gaudi::DataHandle::Reader, this}; // Output collections DataHandle<edm4hep::TrackerHitCollection> m_outputMuonBarrel{"MuonBarrelTrackerHits", Gaudi::DataHandle::Writer, this}; + DataHandle<edm4hep::TrackerHitCollection> m_outputMuonEndcap{"MuonEndcapTrackerHits", Gaudi::DataHandle::Writer, this}; + //DataHandle<edm4hep::MCRecoTrackerAssociationCollection> m_assMuonBarrel{"MuonBarrelTrackerHitAssociationCollection", Gaudi::DataHandle::Writer, this}; edm4hep::TrackerHitCollection* trkhitVec; - int m_nEvt=0; }; #endif