From e537281d4d1ed1abafda1c518904882bcef5fdcf Mon Sep 17 00:00:00 2001 From: Chengdong Fu <fucd@ihep.ac.cn> Date: Mon, 30 May 2022 09:39:31 +0800 Subject: [PATCH] new DC module for MarlinTrk&TOT --- .../CRD_common_v01/DC_Straight_v01_01.xml | 41 +++ .../Tracker/StraightDriftChamber_v01_geo.cpp | 252 ++++++++++++++++++ Digitisers/SimpleDigi/CMakeLists.txt | 1 + Digitisers/SimpleDigi/src/CylinderDigiAlg.cpp | 120 +++++++++ Digitisers/SimpleDigi/src/CylinderDigiAlg.h | 39 +++ Simulation/DetSimSD/CMakeLists.txt | 1 + .../DetSimSD/src/DriftChamberSensDetTool.cpp | 18 +- .../DetSimSD/src/DriftChamberSensDetTool.h | 1 + .../src/TrackerCombineSensitiveDetector.cpp | 56 ++++ .../src/TrackerCombineSensitiveDetector.h | 95 +++++++ 10 files changed, 618 insertions(+), 6 deletions(-) create mode 100644 Detector/DetCRD/compact/CRD_common_v01/DC_Straight_v01_01.xml create mode 100644 Detector/DetCRD/src/Tracker/StraightDriftChamber_v01_geo.cpp create mode 100644 Digitisers/SimpleDigi/src/CylinderDigiAlg.cpp create mode 100644 Digitisers/SimpleDigi/src/CylinderDigiAlg.h create mode 100644 Simulation/DetSimSD/src/TrackerCombineSensitiveDetector.cpp create mode 100644 Simulation/DetSimSD/src/TrackerCombineSensitiveDetector.h diff --git a/Detector/DetCRD/compact/CRD_common_v01/DC_Straight_v01_01.xml b/Detector/DetCRD/compact/CRD_common_v01/DC_Straight_v01_01.xml new file mode 100644 index 00000000..2502ab45 --- /dev/null +++ b/Detector/DetCRD/compact/CRD_common_v01/DC_Straight_v01_01.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="UTF-8"?> +<lccdd> + <info name="DriftChamber" title="Drift Chamber only with straight wire" url="http://github.com/cepc/CEPCSW" author="FU Chengdong" status="development" version="v1"> + <comment>Test with Drift Chamber</comment> + </info> + + <define> + <constant name="DC_cell_size" value="15*mm"/> + <constant name="DC_layer_number" value="int((DC_chamber_layer_rend-DC_chamber_layer_rbegin)/DC_cell_size)"/> + <constant name="DC_sensitive_rmin" value="DC_chamber_layer_rbegin+0.5*(DC_chamber_layer_rend-DC_chamber_layer_rbegin-DC_cell_size*DC_layer_number)"/> + <constant name="DC_sensitive_rmax" value="DC_sensitive_rmin+DC_cell_size*DC_layer_number"/> + </define> + + <detectors> + <detector id="DetID_DC" name="DriftChamber" type="StraightDriftChamber_v01" readout="DriftChamberHitsCollection" vis="DCVis" insideTrackingVolume="true" limits="dc_limits"> + <envelope> + <shape type="BooleanShape" operation="Union" material="Air"> + <shape type="Tube" rmin="DC_inner_radius" rmax="DC_outer_radius" dz="DC_half_length+DC_Endcap_dz" /> + </shape> + </envelope> + + <type_flags type="DetType_TRACKER + DetType_BARREL + DetType_GASEOUS + DetType_WIRE"/> + + <shell> + <inner thickness="SDT_inner_wall_thickness" material="CarbonFiber" vis="LightGrayVis"/> + <outer thickness="SDT_outer_wall_thickness" material="CarbonFiber" vis="LightGrayVis"/> + <side thickness="0.1*mm" material="CarbonFiber" vis="LightGrayVis"/> + </shell> + <chamber rmin="DC_chamber_layer_rbegin" rmax="DC_chamber_layer_rend" zhalf="DC_half_length" material="GasHe_90Isob_10" vis="DCVis"> + <layer id="0" name="MainChamber" rmin="DC_sensitive_rmin" rmax="DC_sensitive_rmax" number="DC_layer_number" material="GasHe_90Isob_10" vis="DCLayerVis"/> + </chamber> + </detector> + </detectors> + + <readouts> + <readout name="DriftChamberHitsCollection"> + <id>system:5,layer:7:9,chamber:8,cellID:32:16</id> + </readout> + </readouts> + +</lccdd> diff --git a/Detector/DetCRD/src/Tracker/StraightDriftChamber_v01_geo.cpp b/Detector/DetCRD/src/Tracker/StraightDriftChamber_v01_geo.cpp new file mode 100644 index 00000000..af878c09 --- /dev/null +++ b/Detector/DetCRD/src/Tracker/StraightDriftChamber_v01_geo.cpp @@ -0,0 +1,252 @@ +//==================================================================== +// Detector description implementation of the Drift Chamber with only straight +//-------------------------------------------------------------------- +// +// Author: Chengdong FU +// +//==================================================================== + +#include <DD4hep/Detector.h> +#include "DD4hep/DetFactoryHelper.h" +#include "XML/Utilities.h" +#include "DDRec/Surface.h" +#include "DDRec/DetectorData.h" + +#include <map> + +using namespace std; + +using dd4hep::DetElement; +using dd4hep::Detector; +using dd4hep::Material; +using dd4hep::PlacedVolume; +using dd4hep::SensitiveDetector; +using dd4hep::Volume; +using dd4hep::Tube; +using dd4hep::_toString; +using dd4hep::Position; +using dd4hep::rec::FixedPadSizeTPCData; +using dd4hep::rec::Vector3D; +using dd4hep::rec::VolCylinder; +using dd4hep::rec::SurfaceType; +using dd4hep::rec::volSurfaceList; +using dd4hep::rec::VolPlane; + +static dd4hep::Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) { + xml_det_t x_det = e; + Material air = description.air(); + int det_id = x_det.id(); + string name = x_det.nameStr(); + DetElement tracker(name, det_id); + + Volume envelope = dd4hep::xml::createPlacedEnvelope(description, e, tracker); + dd4hep::xml::setDetectorTypeFlag(e, tracker) ; + if(description.buildType()==dd4hep::BUILD_ENVELOPE) return tracker; + envelope.setVisAttributes(description.visAttributes("SeeThrough")); + + sens.setType("tracker"); + std::cout << " ** building StraightDriftChamber_v01 ..." << std::endl ; + + xml_coll_t c_shell(x_det,_Unicode(shell)); + xml_comp_t x_shell = c_shell; + + xml_coll_t c_inner(x_shell,_U(inner)); + xml_comp_t x_inner = c_inner; + double thickness_inner = x_inner.thickness(); + Material mat_inner(description.material(x_inner.materialStr())); + + xml_coll_t c_outer(x_shell,_U(outer)); + xml_comp_t x_outer = c_outer; + double thickness_outer = x_outer.thickness(); + Material mat_outer(description.material(x_outer.materialStr())); + + xml_coll_t c_side(x_shell,_U(side)); + xml_comp_t x_side = c_side; + double thickness_side = x_side.thickness(); + Material mat_side(description.material(x_side.materialStr())); + + xml_coll_t c_chamber(x_det,_U(chamber)); + xml_comp_t x_chamber = c_chamber; + double rmin_chamber = x_chamber.rmin(); + double rmax_chamber = x_chamber.rmax(); + double halflength_chamber = x_chamber.zhalf(); + Material mat_chamber(description.material(x_chamber.materialStr())); + + xml_coll_t c_signal(x_det,_Unicode(signal_wire)); + xml_comp_t x_signal = c_signal; + double rmin_signal = x_signal.rmin(); + double rmax_signal = x_signal.rmax(); + Material mat_signal = (description.material(x_signal.materialStr())); + Tube solid_signal(rmin_signal,rmax_signal,halflength_chamber); + Volume volume_signal(name+"_signal",solid_signal,mat_signal); + for(xml_coll_t c(x_signal, _U(tubs)); c; ++c) { + xml_comp_t x_tub = c; + string name_tub = x_tub.nameStr(); + double rmin_tub = x_tub.rmin(); + double rmax_tub = x_tub.rmax(); + Material mat_tub(description.material(x_tub.materialStr())); + Tube solid_tub(rmin_tub,rmax_tub,halflength_chamber); + Volume volume_tub(name+"_signal"+name_tub,solid_tub,mat_tub); + volume_tub.setVisAttributes(description.visAttributes(x_tub.visStr())); + PlacedVolume phy_tub = volume_signal.placeVolume(volume_tub); + } + + xml_coll_t c_field(x_det,_Unicode(field_wire)); + xml_comp_t x_field = c_field; + double rmin_field = x_field.rmin(); + double rmax_field = x_field.rmax(); + Material mat_field = (description.material(x_field.materialStr())); + Tube solid_field(rmin_field,rmax_field,halflength_chamber); + Volume volume_field(name+"_field",solid_field,mat_field); + for(xml_coll_t c(x_field, _U(tubs)); c; ++c) { + xml_comp_t x_tub = c; + string name_tub = x_tub.nameStr(); + double rmin_tub = x_tub.rmin(); + double rmax_tub = x_tub.rmax(); + Material mat_tub(description.material(x_tub.materialStr())); + Tube solid_tub(rmin_tub,rmax_tub,halflength_chamber); + Volume volume_tub(name+"_field"+name_tub,solid_tub,mat_tub); + volume_tub.setVisAttributes(description.visAttributes(x_tub.visStr())); + PlacedVolume phy_tub = volume_field.placeVolume(volume_tub); + } + + Tube solid_chamber(rmin_chamber,rmax_chamber,halflength_chamber); + Volume volume_chamber(name+"_chamber",solid_chamber,mat_chamber); + volume_chamber.setVisAttributes(description.visAttributes(x_chamber.visStr())); + PlacedVolume phy_chamber = envelope.placeVolume(volume_chamber); + if(x_det.hasAttr(_U(id))){ + phy_chamber.addPhysVolID("system",x_det.id()); + } + DetElement det_chamber(tracker, name+"_chamber", 0); + det_chamber.setPlacement(phy_chamber); + + Tube solid_inner(rmin_chamber-thickness_inner, rmin_chamber, halflength_chamber); + Volume volume_inner(name+"_inner_wall",solid_inner,mat_inner); + volume_inner.setVisAttributes(description.visAttributes(x_inner.visStr())); + PlacedVolume phy_inner = envelope.placeVolume(volume_inner); + DetElement det_inner(tracker, name+"_inner_wall", 0); + det_inner.setPlacement(phy_inner); + Vector3D ocyl_inner(rmin_chamber-0.5*thickness_inner, 0., 0.); + VolCylinder surfI(volume_inner, SurfaceType(SurfaceType::Helper), 0.5*thickness_inner, 0.5*thickness_inner, ocyl_inner); + volSurfaceList(tracker)->push_back(surfI); + + Tube solid_outer(rmax_chamber, rmax_chamber+thickness_outer, halflength_chamber); + Volume volume_outer(name+"_outer_wall",solid_outer,mat_outer); + volume_outer.setVisAttributes(description.visAttributes(x_outer.visStr())); + PlacedVolume phy_outer = envelope.placeVolume(volume_outer); + DetElement det_outer(tracker, name+"_outer_wall", 0); + det_outer.setPlacement(phy_outer); + Vector3D ocyl_outer(rmax_chamber+0.5*thickness_inner, 0., 0.); + VolCylinder surfO(volume_outer, SurfaceType(SurfaceType::Helper), 0.5*thickness_outer, 0.5*thickness_outer, ocyl_outer); + volSurfaceList(tracker)->push_back(surfO); + + Tube solid_side(rmin_chamber-thickness_inner, rmax_chamber+thickness_inner, 0.5*thickness_side); + Volume volume_side(name+"_side_wall",solid_side,mat_side); + volume_side.setVisAttributes(description.visAttributes(x_side.visStr())); + PlacedVolume phy_plus = envelope.placeVolume(volume_side,Position(0,0,halflength_chamber+0.5*thickness_side)); + PlacedVolume phy_minus = envelope.placeVolume(volume_side,Position(0,0,-halflength_chamber-0.5*thickness_side)); + DetElement det_plus(tracker, name+"_plusside_wall", 0); + det_plus.setPlacement(phy_plus); + DetElement det_minus(tracker, name+"_minusside_wall", 1); + det_minus.setPlacement(phy_minus); + Vector3D u(0., 1., 0.); + Vector3D v(1., 0., 0.); + Vector3D n(0., 0., 1.); + double mid_r = 0.5*(rmin_chamber-thickness_inner+rmax_chamber+thickness_inner); + Vector3D o(0., mid_r, 0.); + VolPlane surfS(volume_side, SurfaceType(SurfaceType::Helper), 0.5*thickness_side, 0.5*thickness_side, u, v, n, o); + volSurfaceList(det_plus)->push_back(surfS); + volSurfaceList(det_minus)->push_back(surfS); + + int chamber_id=0, max_layer=0; + double rmin_sensitive=10000, rmax_sensitive=0, cell_height=0; + for(xml_coll_t c(x_chamber, _U(layer)); c; ++c) { + xml_comp_t x_layer = c; + string name_layer = x_layer.nameStr(); + double rmin_layer = x_layer.rmin(); + double rmax_layer = x_layer.rmax(); + Material mat_layer(description.material(x_layer.materialStr())); + Tube solid_sub(rmin_layer, rmax_layer, halflength_chamber); + Volume volume_sub(name+name_layer,solid_sub,mat_layer); + volume_sub.setVisAttributes(description.visAttributes("SeeThrough")); + PlacedVolume phy_sub = volume_chamber.placeVolume(volume_sub); + DetElement det_sub(det_chamber, name+name_layer, x_layer.id()); + det_sub.setPlacement(phy_sub); + + int nlayer = x_layer.number(); + double height = (rmax_layer-rmin_layer)/nlayer; + double radius = rmin_layer; + for(int layer_id=0; layer_id<nlayer; layer_id++){ + Tube solid_layer(radius, radius+height, halflength_chamber); + Volume volume_layer(name+name_layer+_toString(layer_id, "_%d"),solid_layer,mat_layer); + volume_layer.setVisAttributes(description.visAttributes(x_layer.visStr())); + + PlacedVolume phy = volume_sub.placeVolume(volume_layer); + if(x_layer.isSensitive()){ + volume_layer.setSensitiveDetector(sens); + volume_layer.setLimitSet(description,x_det.limitsStr()); + phy.addPhysVolID("chamber", chamber_id).addPhysVolID("layer", layer_id); + if(radius<rmin_sensitive){ + rmin_sensitive = radius; + // TODO: more than one chamber, with different height; now only minimum radius chamber include + rmax_sensitive = radius + nlayer*height; + max_layer = nlayer; + cell_height = height; + } + double radius_center = radius+0.5*height; + double radius_edge = radius+rmax_field; + int ncell = floor(dd4hep::twopi*radius_center/height); + double dphi = dd4hep::twopi / ncell; + double offset = 0.; + if(layer_id%2!=0) offset = 0.5*dphi; + //std::cout << "debug: " << layer_id << " rmid=" << radius_center << " redge=" << radius_edge + // << " ncell=" << ncell << " dphi=" << dphi << " offset=" << offset << std::endl; + for(int icell=0;icell<ncell;icell++){ + double phi = (icell+0.5)*dphi + offset; + volume_layer.placeVolume(volume_signal, Position(radius_center*cos(phi),radius_center*sin(phi),0)); + volume_layer.placeVolume(volume_field, Position(radius_center*cos(phi+0.5*dphi),radius_center*sin(phi+0.5*dphi),0)); + volume_layer.placeVolume(volume_field, Position(radius_edge*cos(phi+0.5*dphi),radius_edge*sin(phi+0.5*dphi),0)); + volume_layer.placeVolume(volume_field, Position(radius_edge*cos(phi+0.25*dphi),radius_edge*sin(phi+0.25*dphi),0)); + volume_layer.placeVolume(volume_field, Position(radius_edge*cos(phi),radius_edge*sin(phi),0)); + volume_layer.placeVolume(volume_field, Position(radius_edge*cos(phi-0.25*dphi),radius_edge*sin(phi-0.25*dphi),0)); + + if(layer_id==nlayer){ + double radius_max = radius+height-rmax_field; + volume_layer.placeVolume(volume_field, Position(radius_max*cos(phi+0.5*dphi),radius_max*sin(phi+0.5*dphi),0)); + volume_layer.placeVolume(volume_field, Position(radius_max*cos(phi+0.25*dphi),radius_max*sin(phi+0.25*dphi),0)); + volume_layer.placeVolume(volume_field, Position(radius_max*cos(phi),radius_max*sin(phi),0)); + volume_layer.placeVolume(volume_field, Position(radius_max*cos(phi-0.25*dphi),radius_max*sin(phi-0.25*dphi),0)); + } + } + } + DetElement det_layer(det_sub, name+name_layer+_toString(layer_id, "_%d"), layer_id); + det_layer.setPlacement(phy); + Vector3D ol(radius+0.5*height, 0., 0.); + SurfaceType type = x_layer.isSensitive()?SurfaceType(SurfaceType::Sensitive, SurfaceType::Invisible):SurfaceType(SurfaceType::Helper); + VolCylinder surf(volume_layer, type, 0.5*height, 0.5*height, ol); + volSurfaceList(det_layer)->push_back(surf); + + radius += height; + } + if(x_layer.isSensitive()) chamber_id++; + } + + FixedPadSizeTPCData* dcData = new FixedPadSizeTPCData; + dcData->zHalf = halflength_chamber+thickness_side; + dcData->rMin = rmin_chamber-thickness_inner; + dcData->rMax = rmax_chamber+thickness_outer; + dcData->innerWallThickness = thickness_inner; + dcData->outerWallThickness = thickness_outer; + dcData->rMinReadout = rmin_sensitive; + dcData->rMaxReadout = rmax_sensitive; + dcData->maxRow = max_layer; + dcData->padHeight = cell_height; + dcData->padWidth = cell_height; + dcData->driftLength = halflength_chamber; + dcData->zMinReadout = thickness_side/2.0; + tracker.addExtension<FixedPadSizeTPCData>(dcData); + + return tracker; +} + +DECLARE_DETELEMENT(StraightDriftChamber_v01, create_detector) diff --git a/Digitisers/SimpleDigi/CMakeLists.txt b/Digitisers/SimpleDigi/CMakeLists.txt index 4e2687bc..28c8ea89 100644 --- a/Digitisers/SimpleDigi/CMakeLists.txt +++ b/Digitisers/SimpleDigi/CMakeLists.txt @@ -3,6 +3,7 @@ gaudi_add_module(SimpleDigi SOURCES src/PlanarDigiAlg.cpp src/TPCDigiAlg.cpp src/voxel.cpp + src/CylinderDigiAlg.cpp LINK GearSvc EventSeeder TrackSystemSvcLib diff --git a/Digitisers/SimpleDigi/src/CylinderDigiAlg.cpp b/Digitisers/SimpleDigi/src/CylinderDigiAlg.cpp new file mode 100644 index 00000000..8bc07eed --- /dev/null +++ b/Digitisers/SimpleDigi/src/CylinderDigiAlg.cpp @@ -0,0 +1,120 @@ +#include "CylinderDigiAlg.h" + +#include "edm4hep/Vector3f.h" + +#include "DD4hep/Detector.h" +#include <DD4hep/Objects.h> +#include "DD4hep/DD4hepUnits.h" +#include "DDRec/Vector3D.h" + +#include "GaudiKernel/INTupleSvc.h" +#include "GaudiKernel/MsgStream.h" +#include "GaudiKernel/IRndmGen.h" +#include "GaudiKernel/IRndmGenSvc.h" +#include "GaudiKernel/RndmGenerators.h" + +DECLARE_COMPONENT( CylinderDigiAlg ) + +CylinderDigiAlg::CylinderDigiAlg(const std::string& name, ISvcLocator* svcLoc) +: GaudiAlgorithm(name, svcLoc){ + // Input collections + declareProperty("InputSimTrackerHitCollection", m_inputColHdls, "Handle of the Input SimTrackerHit collection"); + + // Output collections + declareProperty("OutputTrackerHitCollection", m_outputColHdls, "Handle of the output TrackerHit collection"); + declareProperty("TrackerHitAssociationCollection", m_assColHdls, "Handle of the Association collection between SimTrackerHit and TrackerHit"); +} + +StatusCode CylinderDigiAlg::initialize(){ + m_geosvc = service<IGeomSvc>("GeomSvc"); + if(!m_geosvc){ + error() << "Failed to get the GeomSvc" << endmsg; + return StatusCode::FAILURE; + } + auto detector = m_geosvc->lcdd(); + if(!detector){ + error() << "Failed to get the Detector from GeomSvc" << endmsg; + return StatusCode::FAILURE; + } + std::string name = m_inputColHdls.objKey(); + debug() << "Readout name: " << name << endmsg; + m_decoder = m_geosvc->getDecoder(name); + if(!m_decoder){ + error() << "Failed to get the decoder. " << endmsg; + return StatusCode::FAILURE; + } + + info() << "CylinderDigiAlg::initialized" << endmsg; + return GaudiAlgorithm::initialize(); +} + + +StatusCode CylinderDigiAlg::execute(){ + auto trkhitVec = m_outputColHdls.createAndPut(); + auto assVec = m_assColHdls.createAndPut(); + + const edm4hep::SimTrackerHitCollection* STHCol = nullptr; + try { + STHCol = m_inputColHdls.get(); + } + catch(GaudiException &e){ + debug() << "Collection " << m_inputColHdls.fullKey() << " is unavailable in event " << m_nEvt << endmsg; + return StatusCode::SUCCESS; + } + if(STHCol->size()==0) return StatusCode::SUCCESS; + debug() << m_inputColHdls.fullKey() << " has SimTrackerHit "<< STHCol->size() << endmsg; + + for(auto simhit : *STHCol){ + auto particle = simhit.getMCParticle(); + if(!particle.isAvailable()) continue; + + auto& mom0 = particle.getMomentum(); + double pt = sqrt(mom0.x*mom0.x+mom0.y*mom0.y); + if(particle.isCreatedInSimulation()&&pt<0.01&&particle.isStopped()) continue; + + auto cellId = simhit.getCellID(); + int system = m_decoder->get(cellId, "system"); + int chamber = m_decoder->get(cellId, "chamber"); + int layer = m_decoder->get(cellId, "layer" ); + auto& pos = simhit.getPosition(); + auto& mom = simhit.getMomentum(); + + double phi = atan2(pos[1], pos[0]); + double r = sqrt(pos[0]*pos[0]+pos[1]*pos[1]); + double dphi = m_resRPhi/r; + phi += randSvc()->generator(Rndm::Gauss(0, dphi))->shoot(); + double smearedX = r*cos(phi); + double smearedY = r*sin(phi); + double smearedZ = pos[2] + randSvc()->generator(Rndm::Gauss(0, m_resZ))->shoot(); + + auto trkHit = trkhitVec->create(); + trkHit.setCellID(cellId); + trkHit.setTime(simhit.getTime()); + trkHit.setEDep(simhit.getEDep()); + trkHit.setEdx (simhit.getEDep()/simhit.getPathLength()); + trkHit.setPosition (edm4hep::Vector3d(smearedX, smearedY, smearedZ)); + trkHit.setCovMatrix(std::array<float, 6>{m_resRPhi*m_resRPhi/2, 0, m_resRPhi*m_resRPhi/2, 0, 0, m_resZ*m_resZ}); + //trkHit.setType(CEPC::CYLINDER); + trkHit.addToRawHits(simhit.getObjectID()); + debug() << "Hit " << simhit.id() << ": " << pos << " -> " << trkHit.getPosition() << "s:" << system << " c:" << chamber << " l:" << layer + << " pt = " << pt << " " << mom.x << " " << mom.y << " " << mom.z << endmsg; + + auto ass = assVec->create(); + + float weight = 1.0; + + debug() <<" Set relation between " << " sim hit " << simhit.id() << " to tracker hit " << trkHit.id() << " with a weight of " << weight << endmsg; + ass.setSim(simhit); + ass.setRec(trkHit); + ass.setWeight(weight); + } + + m_nEvt++; + + return StatusCode::SUCCESS; +} + +StatusCode CylinderDigiAlg::finalize(){ + info() << "Processed " << m_nEvt << " events " << endmsg; + return GaudiAlgorithm::finalize(); +} diff --git a/Digitisers/SimpleDigi/src/CylinderDigiAlg.h b/Digitisers/SimpleDigi/src/CylinderDigiAlg.h new file mode 100644 index 00000000..af3ffe21 --- /dev/null +++ b/Digitisers/SimpleDigi/src/CylinderDigiAlg.h @@ -0,0 +1,39 @@ +#ifndef CylinderDigiAlg_H +#define CylinderDigiAlg_H + +#include "k4FWCore/DataHandle.h" +#include "GaudiKernel/NTuple.h" +#include "GaudiAlg/GaudiAlgorithm.h" +#include "edm4hep/SimTrackerHitCollection.h" +#include "edm4hep/TrackerHitCollection.h" +#include "edm4hep/MCRecoTrackerAssociationCollection.h" + +#include <DDRec/DetectorData.h> +#include "DetInterface/IGeomSvc.h" + +class CylinderDigiAlg : public GaudiAlgorithm{ + public: + + CylinderDigiAlg(const std::string& name, ISvcLocator* svcLoc); + + virtual StatusCode initialize() ; + virtual StatusCode execute() ; + virtual StatusCode finalize() ; + +protected: + + SmartIF<IGeomSvc> m_geosvc; + dd4hep::DDSegmentation::BitFieldCoder* m_decoder; + + // Input collections + DataHandle<edm4hep::SimTrackerHitCollection> m_inputColHdls{"DriftChamberHitsCollection", Gaudi::DataHandle::Reader, this}; + // Output collections + DataHandle<edm4hep::TrackerHitCollection> m_outputColHdls{"DCTrackerHits", Gaudi::DataHandle::Writer, this}; + DataHandle<edm4hep::MCRecoTrackerAssociationCollection> m_assColHdls{"DCTrackerHitAssociationCollection", Gaudi::DataHandle::Writer, this}; + + Gaudi::Property<float> m_resRPhi{this, "ResRPhi", 0.1}; + Gaudi::Property<float> m_resZ {this, "ResZ", 2.828}; + + int m_nEvt=0; +}; +#endif diff --git a/Simulation/DetSimSD/CMakeLists.txt b/Simulation/DetSimSD/CMakeLists.txt index fa8ba9ef..210e3639 100644 --- a/Simulation/DetSimSD/CMakeLists.txt +++ b/Simulation/DetSimSD/CMakeLists.txt @@ -15,6 +15,7 @@ gaudi_add_module(DetSimSD src/GenericTrackerSensDetTool.cpp src/GenericTrackerSensitiveDetector.cpp + src/TrackerCombineSensitiveDetector.cpp LINK DetSimInterface DetInterface ${DD4hep_COMPONENT_LIBRARIES} diff --git a/Simulation/DetSimSD/src/DriftChamberSensDetTool.cpp b/Simulation/DetSimSD/src/DriftChamberSensDetTool.cpp index 43dfa178..f5ed24ed 100644 --- a/Simulation/DetSimSD/src/DriftChamberSensDetTool.cpp +++ b/Simulation/DetSimSD/src/DriftChamberSensDetTool.cpp @@ -5,7 +5,7 @@ #include "DD4hep/Detector.h" #include "DriftChamberSensitiveDetector.h" - +#include "TrackerCombineSensitiveDetector.h" DECLARE_COMPONENT(DriftChamberSensDetTool) StatusCode DriftChamberSensDetTool::initialize() { @@ -39,12 +39,18 @@ DriftChamberSensDetTool::createSD(const std::string& name) { G4VSensitiveDetector* sd = nullptr; if (name == "DriftChamber") { - DriftChamberSensitiveDetector* dcsd = new DriftChamberSensitiveDetector(name, *dd4hep_geo); - dcsd->setDedxSimTool(m_dedx_simtool); - - sd = dcsd; + if(m_sdTypeOption==0){ + DriftChamberSensitiveDetector* dcsd = new DriftChamberSensitiveDetector(name, *dd4hep_geo); + dcsd->setDedxSimTool(m_dedx_simtool); + sd = dcsd; + } + else if(m_sdTypeOption==1){ + sd = new TrackerCombineSensitiveDetector(name, *dd4hep_geo); + } + } + else{ + warning() << "The SD " << name << " want to use SD for DriftChamber" << endmsg; } - return sd; } diff --git a/Simulation/DetSimSD/src/DriftChamberSensDetTool.h b/Simulation/DetSimSD/src/DriftChamberSensDetTool.h index e01445d5..537ff103 100644 --- a/Simulation/DetSimSD/src/DriftChamberSensDetTool.h +++ b/Simulation/DetSimSD/src/DriftChamberSensDetTool.h @@ -35,6 +35,7 @@ private: SmartIF<IGeomSvc> m_geosvc; ToolHandle<IDedxSimTool> m_dedx_simtool; Gaudi::Property<std::string> m_dedx_sim_option{this, "DedxSimTool"}; + Gaudi::Property<int> m_sdTypeOption{this, "TypeOption", 0}; }; diff --git a/Simulation/DetSimSD/src/TrackerCombineSensitiveDetector.cpp b/Simulation/DetSimSD/src/TrackerCombineSensitiveDetector.cpp new file mode 100644 index 00000000..0d53d3b9 --- /dev/null +++ b/Simulation/DetSimSD/src/TrackerCombineSensitiveDetector.cpp @@ -0,0 +1,56 @@ +#include "TrackerCombineSensitiveDetector.h" + +#include "G4Step.hh" +#include "G4VProcess.hh" +#include "G4SDManager.hh" +#include "DD4hep/DD4hepUnits.h" + +TrackerCombineSensitiveDetector::TrackerCombineSensitiveDetector(const std::string& name, + dd4hep::Detector& description) + : DDG4SensitiveDetector(name, description), + m_hc(nullptr){ + G4String CollName = m_sensitive.hitsCollection(); + collectionName.insert(CollName); +} + +void TrackerCombineSensitiveDetector::Initialize(G4HCofThisEvent* HCE){ + userData.e_cut = m_sensitive.energyCutoff(); + + m_hc = new HitCollection(GetName(), collectionName[0]); + int HCID = G4SDManager::GetSDMpointer()->GetCollectionID(m_hc); + HCE->AddHitsCollection( HCID, m_hc ); +} + +G4bool TrackerCombineSensitiveDetector::ProcessHits(G4Step* step, G4TouchableHistory*){ + dd4hep::sim::Geant4StepHandler h(step); + bool return_code = false; + if ( userData.current == -1 ) userData.start(getCellID(step), step, h.pre); + else if ( !userData.track || userData.current != h.track->GetTrackID() ) { + return_code = userData.extractHit(m_hc) != 0; + userData.start(getCellID(step), step, h.pre); + } + + // ....update ..... + userData.update(step); + + void *prePV = h.volume(h.pre), *postPV = h.volume(h.post); + if ( prePV != postPV ) { + return_code = userData.extractHit(m_hc) != 0; + void* postSD = h.sd(h.post); + if ( 0 != postSD ) { + void* preSD = h.sd(h.pre); + if ( preSD == postSD ) { + // fucd: getCellID(step) for preVolume not postVolume, so should start at next step + //userData.start(getCellID(step), step, h.post); + } + } + } + else if ( userData.track->GetTrackStatus() == fStopAndKill ) { + return_code = userData.extractHit(m_hc) != 0; + } + return return_code; +} + +void TrackerCombineSensitiveDetector::EndOfEvent(G4HCofThisEvent* HCE){ + userData.clear(); +} diff --git a/Simulation/DetSimSD/src/TrackerCombineSensitiveDetector.h b/Simulation/DetSimSD/src/TrackerCombineSensitiveDetector.h new file mode 100644 index 00000000..cf0cb844 --- /dev/null +++ b/Simulation/DetSimSD/src/TrackerCombineSensitiveDetector.h @@ -0,0 +1,95 @@ +// ********************************************************* +// +// $Id: TrackerCombineSensitiveDetector.hh,v 1.0 2022/03/27 + +#ifndef TrackerCombineSensitiveDetector_h +#define TrackerCombineSensitiveDetector_h + +#include "DetSimSD/DDG4SensitiveDetector.h" +#include "DDG4/Defs.h" + +namespace dd4hep { + namespace sim { + struct TrackerCombine { + Geant4TrackerHit pre; + Geant4TrackerHit post; + G4Track* track; + double e_cut; + int current; + long long int cellID; + TrackerCombine() : pre(), post(), track(0), e_cut(0.0), current(-1), cellID(0) {} + void start(long long int cell, G4Step* step, G4StepPoint* point) { + pre.storePoint(step,point); + current = pre.truth.trackID; + track = step->GetTrack(); + cellID = cell; + post = pre; + //std::cout << "start: " << cellID << " " << pre.position << " current = " << current << std::endl; + } + void update(G4Step* step) { + post.storePoint(step,step->GetPostStepPoint()); + pre.truth.deposit += post.truth.deposit; + //std::cout << "update: " << cellID << " " << post.position << " current = " << current << std::endl; + } + void clear() { + pre.truth.clear(); + current = -1; + track = 0; + } + Geant4TrackerHit* extractHit(DDG4SensitiveDetector::HitCollection* c) { + //std::cout << "create Geant4TrackerHit: " << cellID << " current = " << current << " track = " << track << " de = " << pre.truth.deposit << std::endl; + if ( current == -1 || !track ) { + return 0; + } + else if ( pre.truth.deposit <= e_cut && !Geant4Hit::isGeantino(track) ) { + clear(); + return 0; + } + double rho1 = pre.position.Rho(); + double rho2 = post.position.Rho(); + double rho = 0.5*(rho1+rho2); + Position pos = 0.5 * (pre.position + post.position); + double z = pos.z(); + double r = sqrt(rho*rho+z*z); + Position path = post.position - pre.position; + double angle_O_pre_post = acos(-pre.position.Unit().Dot(path.Unit())); + double angle_O_post_pre = acos(post.position.Unit().Dot(path.Unit())); + double angle_O_P_pre = asin(pre.position.R()*sin(angle_O_pre_post)/r); + if(angle_O_pre_post>dd4hep::halfpi||angle_O_post_pre>dd4hep::halfpi){ + bool backward = angle_O_post_pre>angle_O_pre_post; + double angle_O_P_pre = backward ? dd4hep::pi - asin(pre.position.R()*sin(angle_O_pre_post)/r) : asin(pre.position.R()*sin(angle_O_pre_post)/r); + double pre2P = r/sin(angle_O_pre_post)*sin(angle_O_pre_post+angle_O_P_pre); + pos = pre.position + pre2P*path.Unit(); + } + Momentum mom = 0.5 * (pre.momentum + post.momentum); + Geant4TrackerHit* hit = new Geant4TrackerHit(pre.truth.trackID, + pre.truth.pdgID, + pre.truth.deposit, + pre.truth.time); + hit->cellID = cellID; + hit->position = pos; + hit->momentum = mom; + hit->length = path.R();; + clear(); + c->insert(hit); + return hit; + } + }; + } +} + +class TrackerCombineSensitiveDetector: public DDG4SensitiveDetector { + public: + TrackerCombineSensitiveDetector(const std::string& name, dd4hep::Detector& description); + + void Initialize(G4HCofThisEvent* HCE); + G4bool ProcessHits(G4Step* step, G4TouchableHistory* history); + void EndOfEvent(G4HCofThisEvent* HCE); + + protected: + HitCollection* m_hc = nullptr; + + private: + dd4hep::sim::TrackerCombine userData; +}; +#endif -- GitLab