generated from key4hep/k4-project-template
-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Edm4hep extension with DriftChamberDigi and DCH digitizer improvement (…
…#9) * Moove to the nightlies to have edm4hep::RecIonizationCluster * Make a new DriftChamberDigi object available by extending edm4hep * Add cellID to the digitized DCH hits * [DCHDigitizer] protect against negative distance to wire
- Loading branch information
Showing
7 changed files
with
412 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
--- | ||
options: | ||
# should getters / setters be prefixed with get / set? | ||
getSyntax: True | ||
# should POD members be exposed with getters/setters in classes that have them as members? | ||
exposePODMembers: False | ||
includeSubfolder: True | ||
|
||
datatypes: | ||
|
||
extension::DriftChamberDigi: | ||
Description: "Drift chamber digitized hit (before tracking)" | ||
Author: "B. Francois, CERN" | ||
Members: | ||
- uint64_t cellID // ID of the wire that created this hit | ||
- float distanceToWire // smeared distance of closest approach between the wire and the hit | ||
- float zPositionAlongWire // smeared z position in the local wire coordinate system | ||
- float time // time of the hit [ns]. | ||
- float eDep // energy deposited on the hit [GeV]. | ||
- float eDepError // error measured on eDep [GeV]. | ||
OneToManyRelations: | ||
- edm4hep::RecIonizationCluster clusters // ionization clusters that were reconstructed in the cell |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
#pragma once | ||
|
||
// 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" | ||
|
||
// EDM4HEP extension | ||
#include "extension/DriftChamberDigiCollection.h" | ||
|
||
// DD4HEP | ||
#include "DD4hep/Detector.h" // for dd4hep::VolumeManager | ||
#include "DDSegmentation/BitFieldCoder.h" | ||
|
||
/** @class DCHsimpleDigitizerExtendedEdm | ||
* | ||
* Algorithm for creating digitized drift chamber hits (extension::DriftChamberDigi) from edm4hep::SimTrackerHit. | ||
* You have to specify the expected resolution in z and in xy (distance to the wire). The smearing is applied in the wire reference frame. | ||
* | ||
* @author Brieuc Francois | ||
* @date 2023-03 | ||
* | ||
*/ | ||
|
||
class DCHsimpleDigitizerExtendedEdm : public GaudiAlgorithm { | ||
public: | ||
explicit DCHsimpleDigitizerExtendedEdm(const std::string&, ISvcLocator*); | ||
virtual ~DCHsimpleDigitizerExtendedEdm(); | ||
/** Initialize. | ||
* @return status code | ||
*/ | ||
virtual StatusCode initialize() final; | ||
/** Execute. | ||
* @return status code | ||
*/ | ||
virtual StatusCode execute() final; | ||
/** Finalize. | ||
* @return status code | ||
*/ | ||
virtual StatusCode finalize() final; | ||
|
||
private: | ||
// Input sim tracker hit collection name | ||
DataHandle<edm4hep::SimTrackerHitCollection> m_input_sim_hits{"inputSimHits", Gaudi::DataHandle::Reader, this}; | ||
// Output digitized tracker hit collection name | ||
DataHandle<extension::DriftChamberDigiCollection> m_output_digi_hits{"outputDigiHits", Gaudi::DataHandle::Writer, this}; | ||
|
||
// Detector readout name | ||
Gaudi::Property<std::string> m_readoutName{this, "readoutName", "CDCHHits", "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; | ||
|
||
// z position resolution in mm | ||
FloatProperty m_z_resolution{this, "zResolution", 1.0, | ||
"Spatial resolution in the z direction (from reading out the wires at both sides) [mm]"}; | ||
// xy resolution in mm | ||
FloatProperty m_xy_resolution{this, "xyResolution", 0.1, "Spatial resolution in the xy direction [mm]"}; | ||
|
||
// Random Number Service | ||
IRndmGenSvc* m_randSvc; | ||
// Gaussian random number generator used for the smearing of the z position | ||
Rndm::Numbers m_gauss_z; | ||
// Gaussian random number generator used for the smearing of the xy position | ||
Rndm::Numbers m_gauss_xy; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
#include "DCHsimpleDigitizerExtendedEdm.h" | ||
|
||
// DD4hep | ||
#include "DD4hep/Detector.h" | ||
#include "DDRec/Vector3D.h" | ||
|
||
// ROOT | ||
#include "Math/Cylindrical3D.h" | ||
|
||
DECLARE_COMPONENT(DCHsimpleDigitizerExtendedEdm) | ||
|
||
DCHsimpleDigitizerExtendedEdm::DCHsimpleDigitizerExtendedEdm(const std::string& aName, ISvcLocator* aSvcLoc) | ||
: GaudiAlgorithm(aName, aSvcLoc), m_geoSvc("GeoSvc", "DCHsimpleDigitizerExtendedEdm") { | ||
declareProperty("inputSimHits", m_input_sim_hits, "Input sim tracker hit collection name"); | ||
declareProperty("outputDigiHits", m_output_digi_hits, "Output digitized tracker hit collection name"); | ||
} | ||
|
||
DCHsimpleDigitizerExtendedEdm::~DCHsimpleDigitizerExtendedEdm() {} | ||
|
||
StatusCode DCHsimpleDigitizerExtendedEdm::initialize() { | ||
// Initialize random services | ||
if (service("RndmGenSvc", m_randSvc).isFailure()) { | ||
error() << "Couldn't get RndmGenSvc!" << endmsg; | ||
return StatusCode::FAILURE; | ||
} | ||
if (m_gauss_z.initialize(m_randSvc, Rndm::Gauss(0., m_z_resolution)).isFailure()) { | ||
error() << "Couldn't initialize RndmGenSvc!" << endmsg; | ||
return StatusCode::FAILURE; | ||
} | ||
if (m_gauss_xy.initialize(m_randSvc, Rndm::Gauss(0., m_xy_resolution)).isFailure()) { | ||
error() << "Couldn't initialize RndmGenSvc!" << endmsg; | ||
return StatusCode::FAILURE; | ||
} | ||
|
||
// check if readout exists | ||
if (m_geoSvc->lcdd()->readouts().find(m_readoutName) == m_geoSvc->lcdd()->readouts().end()) { | ||
error() << "Readout <<" << m_readoutName << ">> does not exist." << endmsg; | ||
return StatusCode::FAILURE; | ||
} | ||
// set the cellID decoder | ||
m_decoder = m_geoSvc->lcdd()->readout(m_readoutName).idSpec().decoder(); | ||
// retrieve the volume manager | ||
m_volman = m_geoSvc->lcdd()->volumeManager(); | ||
|
||
return StatusCode::SUCCESS; | ||
} | ||
|
||
StatusCode DCHsimpleDigitizerExtendedEdm::execute() { | ||
// Get the input collection with Geant4 hits | ||
const edm4hep::SimTrackerHitCollection* input_sim_hits = m_input_sim_hits.get(); | ||
debug() << "Input Sim Hit collection size: " << input_sim_hits->size() << endmsg; | ||
|
||
// Digitize the sim hits | ||
extension::DriftChamberDigiCollection* 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 wire local frame to smear in the direction aligned/perpendicular with the wire for z/distanceToWire, taking e.g. stereo angle into account | ||
// retrieve the cell detElement | ||
dd4hep::DDSegmentation::CellID cellID = input_sim_hit.getCellID(); | ||
auto cellDetElement = m_volman.lookupDetElement(cellID); | ||
// retrieve the wire (in DD4hep 1.23 there is no easy way to access the volume daughters we have to pass by detElements, in later versions volumes can be used) | ||
const std::string& wireDetElementName = | ||
Form("superLayer_%d_layer_%d_phi_%d_wire", m_decoder->get(cellID, "superLayer"), | ||
m_decoder->get(cellID, "layer"), m_decoder->get(cellID, "phi")); | ||
dd4hep::DetElement wireDetElement = cellDetElement.child(wireDetElementName); | ||
// get the transformation matrix used to place the wire | ||
const auto& wireTransformMatrix = wireDetElement.nominal().worldTransformation(); | ||
// 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}; | ||
double simHitLocalPosition[3] = {0, 0, 0}; | ||
// get the simHit coordinate in cm in the wire reference frame to be able to apply smearing of radius perpendicular to the wire | ||
wireTransformMatrix.MasterToLocal(simHitGlobalPosition, simHitLocalPosition); | ||
debug() << "Cell ID string: " << m_decoder->valueString(cellID) << endmsg; | ||
; | ||
debug() << "Global simHit x " << simHitGlobalPosition[0] << " --> Local simHit x " << simHitLocalPosition[0] | ||
<< " in cm" << endmsg; | ||
debug() << "Global simHit y " << simHitGlobalPosition[1] << " --> Local simHit y " << simHitLocalPosition[1] | ||
<< " in cm" << endmsg; | ||
debug() << "Global simHit z " << simHitGlobalPosition[2] << " --> Local simHit z " << simHitLocalPosition[2] | ||
<< " in cm" << endmsg; | ||
// build a vector to easily apply smearing of distance to the wire | ||
dd4hep::rec::Vector3D simHitLocalPositionVector(simHitLocalPosition[0], simHitLocalPosition[1], | ||
simHitLocalPosition[2]); | ||
// get the smeared distance to the wire (cylindrical coordinate as the smearing should be perpendicular to the wire) | ||
debug() << "Original distance to wire: " << simHitLocalPositionVector.rho() << endmsg; | ||
double smearedDistanceToWire = simHitLocalPositionVector.rho() + m_gauss_xy.shoot() * dd4hep::mm; | ||
while(smearedDistanceToWire < 0){ | ||
debug() << "Negative smearedDistanceToWire (" << smearedDistanceToWire << ") shooting another random number" << endmsg; | ||
smearedDistanceToWire = simHitLocalPositionVector.rho() + m_gauss_xy.shoot() * dd4hep::mm; | ||
} | ||
debug() << "Smeared distance to wire: " << smearedDistanceToWire << endmsg; | ||
// smear the z position (in local coordinate the z axis is aligned with the wire i.e. it take the stereo angle into account); | ||
double smearedZ = simHitLocalPositionVector.z() + m_gauss_z.shoot() * dd4hep::mm; | ||
// fill the output DriftChamberDigi (making sure we are back in mm) | ||
output_digi_hit.setCellID(cellID); | ||
output_digi_hit.setDistanceToWire(smearedDistanceToWire / dd4hep::mm); | ||
output_digi_hit.setZPositionAlongWire(smearedZ / dd4hep::mm); | ||
} | ||
debug() << "Output Digi Hit collection size: " << output_digi_hits->size() << endmsg; | ||
return StatusCode::SUCCESS; | ||
} | ||
|
||
StatusCode DCHsimpleDigitizerExtendedEdm::finalize() { return StatusCode::SUCCESS; } |
Oops, something went wrong.