Skip to content

Commit

Permalink
First version of VTX digitisation for IDEA vertex detector (#11)
Browse files Browse the repository at this point in the history
* First push of VTX changes, not  working yet

* First version of Vertex digitisation, smearing in wrong directions still, wrong world transformation

* First working version of VTX digitisation. Currently only one subdetector can be digitised at the same time (don't know why) and it's just gaussian smearing the hits

* Proper formating

* Also working for CLD (change uncommented lines), but only using depreciated readoutNames usage

* Adding Silicon Wrapper and changing to use K4GEO install in software stack

* Added test for vertex digitiser, that works

* Added forcing hits onto Si surface and added silicon wrapper digitisation
  • Loading branch information
armin-ilg authored Dec 19, 2023
1 parent 60ca6ba commit 02cf300
Show file tree
Hide file tree
Showing 6 changed files with 405 additions and 37 deletions.
1 change: 0 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ MAKEFLAGS += --no-print-directory
make:
@ mkdir -p build install ; \
cd build ; \
source /cvmfs/sw-nightlies.hsf.org/key4hep/setup.sh ; \
cmake .. -DCMAKE_INSTALL_PREFIX=../install ; \
make install -j4 ; \
cd .. ; \
Expand Down
38 changes: 24 additions & 14 deletions Tracking/test/runGenFitTrackingOnSimplifiedDriftChamber.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,32 +91,42 @@
saveDCHsimHitTool = SimG4SaveTrackerHits("saveDCHsimHitTool", readoutNames=["SimplifiedDriftChamberCollection"])
saveDCHsimHitTool.SimTrackHits.Path = "DC_simTrackerHits"

saveVTXBsimHitTool = SimG4SaveTrackerHits("saveVTXBsimHitTool", readoutNames=["VertexBarrelCollection"])
saveVTXBsimHitTool.SimTrackHits.Path = "VTXB_simTrackerHits"
saveVTXIBsimHitTool = SimG4SaveTrackerHits("saveVTXIBsimHitTool", readoutNames=["VTXIBCollection"])
saveVTXIBsimHitTool.SimTrackHits.Path = "VTXIB_simTrackerHits"

saveVTXEsimHitTool = SimG4SaveTrackerHits("saveVTXEsimHitTool", readoutNames=["VertexEndcapCollection"])
saveVTXEsimHitTool.SimTrackHits.Path = "VTXE_simTrackerHits"
saveVTXOBsimHitTool = SimG4SaveTrackerHits("saveVTXOBsimHitTool", readoutNames=["VTXOBCollection"])
saveVTXOBsimHitTool.SimTrackHits.Path = "VTXOB_simTrackerHits"

saveVTXDsimHitTool = SimG4SaveTrackerHits("saveVTXDsimHitTool", readoutNames=["VTXDCollection"])
saveVTXDsimHitTool.SimTrackHits.Path = "VTXD_simTrackerHits"

from Configurables import SimG4Alg
geantsim = SimG4Alg("SimG4Alg",
outputs= [saveVTXBsimHitTool, saveVTXEsimHitTool, saveDCHsimHitTool,
outputs= [saveVTXIBsimHitTool, saveVTXOBsimHitTool, saveVTXDsimHitTool, saveDCHsimHitTool,
#saveHistTool
],
eventProvider = particle_converter,
OutputLevel = INFO)

# Digitize tracker hits (for now digitization is reconstruction)
vtxb_reco_hit_name = saveVTXBsimHitTool.SimTrackHits.Path.replace("sim", "reco")
vtxib_reco_hit_name = saveVTXIBsimHitTool.SimTrackHits.Path.replace("sim", "reco")
from Configurables import VTXdigitizer
vtxib_digitizer = VTXdigitizer("VTXIBdigitizer",
inputSimHits = saveVTXIBsimHitTool.SimTrackHits.Path,
outputDigiHits = vtxib_reco_hit_name
)

vtxob_reco_hit_name = saveVTXOBsimHitTool.SimTrackHits.Path.replace("sim", "reco")
from Configurables import VTXdigitizer
vtxb_digitizer = VTXdigitizer("VTXBdigitizer",
inputSimHits = saveVTXBsimHitTool.SimTrackHits.Path,
outputDigiHits = vtxb_reco_hit_name
vtxob_digitizer = VTXdigitizer("VTXOBdigitizer",
inputSimHits = saveVTXOBsimHitTool.SimTrackHits.Path,
outputDigiHits = vtxob_reco_hit_name
)

vtxe_reco_hit_name = saveVTXEsimHitTool.SimTrackHits.Path.replace("sim", "reco")
vtxe_digitizer = VTXdigitizer("VTXEdigitizer",
inputSimHits = saveVTXEsimHitTool.SimTrackHits.Path,
outputDigiHits = vtxe_reco_hit_name
vtxd_reco_hit_name = saveVTXDsimHitTool.SimTrackHits.Path.replace("sim", "reco")
vtxd_digitizer = VTXdigitizer("VTXDdigitizer",
inputSimHits = saveVTXDsimHitTool.SimTrackHits.Path,
outputDigiHits = vtxd_reco_hit_name
)

dch_reco_hit_name = saveDCHsimHitTool.SimTrackHits.Path.replace("sim", "reco")
Expand Down Expand Up @@ -161,7 +171,7 @@
hepmc_converter,
geantsim,
vtxb_digitizer,
vtxe_digitizer,
vtxd_digitizer,
dch_digitizer,
genfitter,
out
Expand Down
4 changes: 4 additions & 0 deletions VTXdigi/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ gaudi_add_module(${PackageName}
Gaudi::GaudiKernel
EDM4HEP::edm4hep
k4FWCore::k4FWCore
DD4hep::DDRec
)

target_include_directories(${PackageName} PUBLIC
Expand All @@ -39,3 +40,6 @@ install(TARGETS ${PackageName}
)

install(FILES ${scripts} DESTINATION test)

SET(test_name "test_runVTXdigitizer")
ADD_TEST(NAME t_${test_name} COMMAND k4run test/runVTXdigitizer.py)
44 changes: 44 additions & 0 deletions VTXdigi/include/VTXdigitizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,24 @@
// GAUDI
#include "Gaudi/Property.h"
#include "GaudiAlg/GaudiAlgorithm.h"
#include "GaudiKernel/IRndmGenSvc.h"
#include "GaudiKernel/RndmGenerators.h"

// K4FWCORE
#include "k4FWCore/DataHandle.h"
#include "k4Interface/IGeoSvc.h"

// EDM4HEP
#include "edm4hep/SimTrackerHitCollection.h"
#include "edm4hep/TrackerHitCollection.h"

// DD4HEP
#include "DD4hep/Detector.h" // for dd4hep::VolumeManager
#include "DDRec/Vector3D.h"
#include "DDRec/SurfaceManager.h"

#include "DDSegmentation/BitFieldCoder.h"

/** @class VTXdigitizer
*
* Algorithm for creating digitized (meaning 'reconstructed' for now) vertex detector hits (edm4hep::TrackerHit) from Geant4 hits (edm4hep::SimTrackerHit).
Expand Down Expand Up @@ -42,4 +52,38 @@ class VTXdigitizer : public GaudiAlgorithm {
DataHandle<edm4hep::SimTrackerHitCollection> m_input_sim_hits{"inputSimHits", Gaudi::DataHandle::Reader, this};
// Output digitized vertex hit collection name
DataHandle<edm4hep::TrackerHitCollection> m_output_digi_hits{"outputDigiHits", Gaudi::DataHandle::Writer, this};

// Detector name
Gaudi::Property<std::string> m_detectorName{this, "detectorName", "Vertex", "Name of the detector (default: Vertex)"};
// Detector readout names
Gaudi::Property<std::string> m_readoutName{this, "readoutName", "VertexBarrelCollection", "Name of the detector readout"};
// Pointer to the geometry service
ServiceHandle<IGeoSvc> m_geoSvc;
// Decoder for the cellID
dd4hep::DDSegmentation::BitFieldCoder* m_decoder;
// Volume manager to get the physical cell sensitive volume
dd4hep::VolumeManager m_volman;

// x resolution in um
FloatProperty m_x_resolution{this, "xResolution", 0.1, "Spatial resolution in the x direction [um] (r-phi direction in barrel, z direction in disks)"};

// y resolution in um
FloatProperty m_y_resolution{this, "yResolution", 0.1, "Spatial resolution in the y direction [um] (r direction in barrel, r-phi direction in disks)"};

// t resolution in ns
FloatProperty m_t_resolution{this, "tResolution", 0.1, "Time resolution [ns]"};

// Surface manager used to project hits onto sensitive surface with forceHitsOntoSurface argument
const dd4hep::rec::SurfaceMap* _map;

// Option to force hits onto sensitive surface
BooleanProperty m_forceHitsOntoSurface{this, "forceHitsOntoSurface", false, "Project hits onto the surface in case they are not yet on the surface (default: false"};

// Random Number Service
IRndmGenSvc* m_randSvc;

// Gaussian random number generator used for smearing
Rndm::Numbers m_gauss_x;
Rndm::Numbers m_gauss_y;
Rndm::Numbers m_gauss_time;
};
155 changes: 152 additions & 3 deletions VTXdigi/src/VTXdigitizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,175 @@

DECLARE_COMPONENT(VTXdigitizer)

VTXdigitizer::VTXdigitizer(const std::string& aName, ISvcLocator* aSvcLoc) : GaudiAlgorithm(aName, aSvcLoc) {
VTXdigitizer::VTXdigitizer(const std::string& aName, ISvcLocator* aSvcLoc)
: GaudiAlgorithm(aName, aSvcLoc), m_geoSvc("GeoSvc", "VTXdigitizer") {
declareProperty("inputSimHits", m_input_sim_hits, "Input sim vertex hit collection name");
declareProperty("outputDigiHits", m_output_digi_hits, "Output digitized vertex hit collection name");
}

VTXdigitizer::~VTXdigitizer() {}

StatusCode VTXdigitizer::initialize() { return StatusCode::SUCCESS; }
StatusCode VTXdigitizer::initialize() {
// Initialize random services
if (service("RndmGenSvc", m_randSvc).isFailure()) {
error() << "Couldn't get RndmGenSvc!" << endmsg;
return StatusCode::FAILURE;
}
if (m_gauss_x.initialize(m_randSvc, Rndm::Gauss(0., m_x_resolution)).isFailure()) {
error() << "Couldn't initialize RndmGenSvc!" << endmsg;
return StatusCode::FAILURE;
}
if (m_gauss_y.initialize(m_randSvc, Rndm::Gauss(0., m_y_resolution)).isFailure()) {
error() << "Couldn't initialize RndmGenSvc!" << endmsg;
return StatusCode::FAILURE;
}
if (m_gauss_time.initialize(m_randSvc, Rndm::Gauss(0., m_t_resolution)).isFailure()) {
error() << "Couldn't initialize RndmGenSvc!" << endmsg;
return StatusCode::FAILURE;
}

// check if readout exists
if (m_geoSvc->getDetector()->readouts().find(m_readoutName) == m_geoSvc->getDetector()->readouts().end()) {
error() << "Readout <<" << m_readoutName << ">> does not exist." << endmsg;
return StatusCode::FAILURE;
}

// set the cellID decoder
m_decoder = m_geoSvc->getDetector()->readout(m_readoutName).idSpec().decoder(); // Can be used to access e.g. layer index: m_decoder->get(cellID, "layer"),

// retrieve the volume manager
m_volman = m_geoSvc->getDetector()->volumeManager();

return StatusCode::SUCCESS;
}

StatusCode VTXdigitizer::execute() {
// Get the input collection with Geant4 hits
const edm4hep::SimTrackerHitCollection* input_sim_hits = m_input_sim_hits.get();
verbose() << "Input Sim Hit collection size: " << input_sim_hits->size() << endmsg;

unsigned nDismissedHits=0;

// Digitize the sim hits
edm4hep::TrackerHitCollection* output_digi_hits = m_output_digi_hits.createAndPut();
for (const auto& input_sim_hit : *input_sim_hits) {
auto output_digi_hit = output_digi_hits->create();

// smear the hit position: need to go in the local frame of the silicon sensor to smear in the direction along/perpendicular to the stave

// retrieve the cell detElement
dd4hep::DDSegmentation::CellID cellID = input_sim_hit.getCellID();
debug() << "Digitisation of " << m_readoutName << ", cellID: " << cellID << endmsg;

// Get transformation matrix of sensor
const auto& sensorTransformMatrix = m_volman.lookupVolumePlacement(cellID).matrix();

// Retrieve global position in mm and apply unit transformation (translation matrix is stored in cm)
double simHitGlobalPosition[3] = {input_sim_hit.getPosition().x * dd4hep::mm,
input_sim_hit.getPosition().y * dd4hep::mm,
input_sim_hit.getPosition().z * dd4hep::mm};
dd4hep::rec::Vector3D simHitGlobalPositionVector(simHitGlobalPosition[0], simHitGlobalPosition[1],
simHitGlobalPosition[2]);
double simHitLocalPosition[3] = {0, 0, 0};

if(m_forceHitsOntoSurface){
dd4hep::Detector& theDetector = dd4hep::Detector::getInstance();
dd4hep::rec::SurfaceManager& surfMan = *theDetector.extension<dd4hep::rec::SurfaceManager>() ;
dd4hep::DetElement det = m_geoSvc->getDetector()->detector(m_detectorName) ;
_map = surfMan.map( det.name() ) ;

if( ! _map )
error() << " Could not find surface map for detector " << det.name() << " in SurfaceManager " << endmsg;

dd4hep::rec::SurfaceMap::const_iterator sI = _map->find(cellID) ;
if( sI == _map->end() )
error() << " VTXdigitizer: no surface found for cellID " << m_decoder->valueString(cellID) << std::endl << endmsg;

dd4hep::rec::Vector3D newPos ;
const dd4hep::rec::ISurface* surf = sI->second ;

// Check if Hit is inside sensitive
if ( ! surf->insideBounds( simHitGlobalPositionVector ) ) {

info() << "Hit at " << simHitGlobalPositionVector << " is not on surface " << *surf
<< ". Distance: " << surf->distance(simHitGlobalPositionVector )
<< std::endl << endmsg;

if( m_forceHitsOntoSurface ){
dd4hep::rec::Vector2D lv = surf->globalToLocal(simHitGlobalPositionVector) ;
dd4hep::rec::Vector3D oldPosOnSurf = surf->localToGlobal( lv ) ;

info() << "Moved hit to " << oldPosOnSurf << ", distance " << (oldPosOnSurf-simHitGlobalPositionVector).r()
<< std::endl << endmsg;

simHitGlobalPositionVector = oldPosOnSurf ;
}
else
++nDismissedHits;
}
}

// get the simHit coordinate in cm in the sensor reference frame to be able to apply smearing
sensorTransformMatrix.MasterToLocal(simHitGlobalPosition, simHitLocalPosition);
debug() << "Cell ID string: " << m_decoder->valueString(cellID) << endmsg;
;
debug() << "Global simHit x " << simHitGlobalPosition[0] << " [mm] --> Local simHit x " << simHitLocalPosition[0]
<< " [cm]" << endmsg;
debug() << "Global simHit y " << simHitGlobalPosition[1] << " [mm] --> Local simHit y " << simHitLocalPosition[1]
<< " [cm]" << endmsg;
debug() << "Global simHit z " << simHitGlobalPosition[2] << " [mm] --> Local simHit z " << simHitLocalPosition[2]
<< " [cm]" << endmsg;

// build a vector to easily apply smearing of distance to the wire
dd4hep::rec::Vector3D simHitLocalPositionVector(simHitLocalPosition[0], simHitLocalPosition[1],
simHitLocalPosition[2]);

// Smear the hit in the local sensor coordinates
double digiHitLocalPosition[3];
if (m_readoutName == "VTXIBCollection" ||
m_readoutName == "VTXOBCollection" ||
m_readoutName == "VertexBarrelCollection" ||
m_readoutName == "SiWrBCollection") { // In barrel, the sensor box is along y-z
digiHitLocalPosition[0] = simHitLocalPositionVector.x();
digiHitLocalPosition[1] = simHitLocalPositionVector.y() + m_gauss_x.shoot() * dd4hep::mm;
digiHitLocalPosition[2] = simHitLocalPositionVector.z() + m_gauss_y.shoot() * dd4hep::mm;
} else if (m_readoutName == "VTXDCollection" ||
m_readoutName == "VertexEndcapCollection" ||
m_readoutName == "SiWrDCollection") { // In the disks, the sensor box is already in x-y
digiHitLocalPosition[0] = simHitLocalPositionVector.x() + m_gauss_x.shoot() * dd4hep::mm;
digiHitLocalPosition[1] = simHitLocalPositionVector.y() + m_gauss_y.shoot() * dd4hep::mm;
digiHitLocalPosition[2] = simHitLocalPositionVector.z();
} else {
error()
<< "VTX readout name (m_readoutName) unknown!"
<< endmsg;
return StatusCode::FAILURE;
}

// go back to the global frame
double digiHitGlobalPosition[3] = {0, 0, 0};
sensorTransformMatrix.LocalToMaster(digiHitLocalPosition, digiHitGlobalPosition);

// go back to mm
edm4hep::Vector3d digiHitGlobalPositionVector(digiHitGlobalPosition[0] / dd4hep::mm,
digiHitGlobalPosition[1] / dd4hep::mm,
digiHitGlobalPosition[2] / dd4hep::mm);

debug() << "Global digiHit x " << digiHitGlobalPositionVector[0] << " [mm] --> Local digiHit x "
<< digiHitLocalPosition[0] << " [cm]" << endmsg;
debug() << "Global digiHit y " << digiHitGlobalPositionVector[1] << " [mm] --> Local digiHit y "
<< digiHitLocalPosition[1] << " [cm]" << endmsg;
debug() << "Global digiHit z " << digiHitGlobalPositionVector[2] << " [mm] --> Local digiHit z "
<< digiHitLocalPosition[2] << " [cm]" << endmsg;
debug() << "Moving to next hit... " << std::endl << endmsg;

output_digi_hit.setEDep(input_sim_hit.getEDep());
output_digi_hit.setPosition(input_sim_hit.getPosition());
output_digi_hit.setPosition(digiHitGlobalPositionVector);

// Apply time smearing
output_digi_hit.setTime(input_sim_hit.getTime() + m_gauss_time.shoot());

output_digi_hit.setCellID(cellID);
}
return StatusCode::SUCCESS;
}
Expand Down
Loading

0 comments on commit 02cf300

Please sign in to comment.