ATLAS Offline Software
PixelSiLorentzAngleCondAlg.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
7 #include "GaudiKernel/PhysicalConstants.h"
9 
13 
14 PixelSiLorentzAngleCondAlg::PixelSiLorentzAngleCondAlg(const std::string& name, ISvcLocator* pSvcLocator):
15  ::AthReentrantAlgorithm(name, pSvcLocator)
16 {
17 }
18 
20  ATH_MSG_DEBUG("PixelSiLorentzAngleCondAlg::initialize()");
21 
22  const PixelID* idHelper{nullptr};
23  ATH_CHECK(detStore()->retrieve(idHelper, m_pixelIDName.value()));
24 
25  m_maxHash = idHelper->wafer_hash_max();
26 
30 
31  ATH_CHECK(m_siPropertiesTool.retrieve());
32 
35 
37 
38  if(m_disable3D) ATH_MSG_INFO("Running with Lorentz correction disabled for 3D pixels");
39 
40  return StatusCode::SUCCESS;
41 }
42 
45 PixelSiLorentzAngleCondAlg::execute(const EventContext& ctx) const {
47 
48  ATH_MSG_DEBUG("PixelSiLorentzAngleCondAlg::execute()");
49 
51  if (writeHandle.isValid()) {
52  ATH_MSG_DEBUG("CondHandle " << writeHandle.fullKey() << " is already valid." << " In theory this should not be called, but may happen" << " if multiple concurrent events are being processed out of order.");
53  return StatusCode::SUCCESS;
54  }
55 
56  // Read Cond Handle (temperature)
58  const PixelDCSTempData* readCdoTemp(*readHandleTemp);
59  if (readCdoTemp==nullptr) {
60  ATH_MSG_FATAL("Null pointer to the read conditions object");
61  return StatusCode::FAILURE;
62  }
63  writeHandle.addDependency(readHandleTemp);
64  ATH_MSG_DEBUG("Input is " << readHandleTemp.fullKey() << " with the range of " << readHandleTemp.getRange());
65 
66  // Read Cond Handle (HV)
68  const PixelDCSHVData* readCdoHV(*readHandleHV);
69  if (readCdoHV==nullptr) {
70  ATH_MSG_FATAL("Null pointer to the read conditions object");
71  return StatusCode::FAILURE;
72  }
73  writeHandle.addDependency(readHandleHV);
74  ATH_MSG_DEBUG("Input is " << readHandleHV.fullKey() << " with the range of " << readHandleHV.getRange());
75 
76  // Field cache object for field calculations
77  MagField::AtlasFieldCache fieldCache;
78  if (m_useMagFieldCache) {
80  // Get field cache object
82  const AtlasFieldCacheCondObj* fieldCondObj{*readHandleField};
83 
84  if (fieldCondObj == nullptr) {
85  ATH_MSG_ERROR("PixelSiLorentzAngleCondAlg: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCondObjInputKey.key());
86  return StatusCode::FAILURE;
87  }
88  //WL: The previous implementation didn't intersect the range of this readHanlde.
89  //I suspect that was a bug.
90  writeHandle.addDependency(readHandleField);
91  fieldCondObj->getInitializedCache (fieldCache);
93 
94  if (m_useMagFieldDcs) {
95  // Read Cond Handle (B field sensor)
97  const CondAttrListCollection* readCdoBFieldSensor(*readHandleBFieldSensor);
98  if (readCdoBFieldSensor==nullptr) {
99  ATH_MSG_FATAL("Null pointer to the read conditions object");
100  return StatusCode::FAILURE;
101  }
102  writeHandle.addDependency(readHandleBFieldSensor);
103  ATH_MSG_DEBUG("Input is " << readHandleBFieldSensor.fullKey() << " with the range of " << readHandleBFieldSensor.getRange() );
104 
105  }//end if useMagFieldDcs
106  }//end if useMagFieldSvc
107 
108 
110  const InDetDD::SiDetectorElementCollection* elements(pixelDetEle.retrieve());
111  if (elements==nullptr) {
112  ATH_MSG_FATAL(m_pixelDetEleCollKey.fullKey() << " could not be retrieved");
113  return StatusCode::FAILURE;
114  }
115  writeHandle.addDependency(pixelDetEle);
116 
117  // Construct the output Cond Object and fill it in
118  std::unique_ptr<SiLorentzAngleCondData> writeCdo{std::make_unique<SiLorentzAngleCondData>()};
119  const PixelID::size_type wafer_hash_max = m_maxHash;
120  writeCdo->resize(wafer_hash_max);
121  for (PixelID::size_type hash = 0; hash < wafer_hash_max; hash++) {
122  const IdentifierHash elementHash = static_cast<IdentifierHash::value_type>(hash);
123 
124  double temperature = readCdoTemp->getTemperature(elementHash)+273.15;
125  double deplVoltage = 0.0*CLHEP::volt;
126  double biasVoltage = readCdoHV->getBiasVoltage(elementHash)*CLHEP::volt;
127 
128  ATH_MSG_DEBUG("Pixel Hash = " << elementHash << " Temperature = " << temperature << " [deg K], BiasV = " << biasVoltage << " DeplV = " << deplVoltage);
129 
130  const InDetDD::SiDetectorElement* element = elements->getDetectorElement(elementHash);
131  double depletionDepth = element->thickness();
132  if (std::fabs(biasVoltage) < std::fabs(deplVoltage)) {
133  depletionDepth *= std::sqrt(std::fabs(biasVoltage/deplVoltage));
134  }
135 
136  const InDetDD::PixelModuleDesign* p_design = dynamic_cast<const InDetDD::PixelModuleDesign*>(&element->design());
137 
138  if (not p_design){
139  ATH_MSG_FATAL("Dynamic cast to PixelModuleDesign* failed in PixelSiLorentzAngleCondAlg::execute");
140  return StatusCode::FAILURE;
141  }
142  double forceLorentzToZero = 1.0;
143  if ((p_design->getReadoutTechnology()==InDetDD::PixelReadoutTechnology::FEI4 && p_design->numberOfCircuits()==1 && p_design->rowsPerCircuit()>100) // IBL 3D
144  || (m_disable3D && p_design->is3D())) { // ITk L0 + L0.5
145  forceLorentzToZero = 0.0;
146  }
147 
148  const InDet::SiliconProperties &siProperties = m_siPropertiesTool->getSiProperties(elementHash, ctx);
149  double mobility = siProperties.signedHallMobility(element->carrierType());
150 
151  // Get magnetic field. This first checks that field cache is valid.
152  Amg::Vector3D magneticField = getMagneticField(fieldCache,element);
153 
154  // The angles are in the hit frame. This is because that is what is needed by the digization and also
155  // gives a more physical sign of the angle (ie dosen't flip sign when the detector is flipped).
156  // The hit depth axis is pointing from the readout side to the backside if m_design->readoutSide() < 0
157  // The hit depth axis is pointing from the backside to the readout side if m_design->readoutSide() > 0
158  double tanLorentzAnglePhi = forceLorentzToZero*element->design().readoutSide()*mobility*element->hitDepthDirection()*element->hitPhiDirection()*(element->normal().cross(magneticField)).dot(element->phiAxis());
159  writeCdo->setTanLorentzAngle(elementHash, tanLorentzAnglePhi);
160 
161  // This gives the effective correction in the reconstruction frame hence the extra hitPhiDirection()
162  // as the angle above is in the hit frame.
163  double lorentzCorrectionPhi = -0.5*element->hitPhiDirection()*tanLorentzAnglePhi*depletionDepth;
164  writeCdo->setLorentzShift(elementHash, lorentzCorrectionPhi);
165 
166  // The Lorentz eta shift very small and so can be ignored, but we include it for completeness.
167  double tanLorentzAngleEta = forceLorentzToZero*element->design().readoutSide()*mobility*element->hitDepthDirection()*element->hitEtaDirection()*(element->normal().cross(magneticField)).dot(element->etaAxis());
168  writeCdo->setTanLorentzAngleEta(elementHash, tanLorentzAngleEta);
169  double lorentzCorrectionEta = -0.5*element->hitPhiDirection()*tanLorentzAngleEta*depletionDepth;
170  writeCdo->setLorentzShiftEta(elementHash, lorentzCorrectionEta);
171 
172  // Monitoring value
173  writeCdo->setBiasVoltage(elementHash, biasVoltage/CLHEP::volt);
174  writeCdo->setTemperature(elementHash, temperature-273.15);
175  writeCdo->setDepletionVoltage(elementHash, deplVoltage/CLHEP::volt);
176 
177  ATH_MSG_DEBUG("Hash = " << elementHash << " tanPhi = " << lorentzCorrectionPhi << " shiftPhi = " << writeCdo->getLorentzShift(elementHash) << " Factor = 1.0 Depletion depth = " << depletionDepth);
178  ATH_MSG_DEBUG("Hash = " << elementHash << " tanPhi = " << lorentzCorrectionPhi << " shiftPhi = " << writeCdo->getLorentzShift(elementHash) << "Depletion depth = " << depletionDepth);
179  ATH_MSG_VERBOSE("Temperature (C), bias voltage, depletion voltage: " << temperature-273.15 << ", " << biasVoltage/CLHEP::volt << ", " << deplVoltage/CLHEP::volt);
180  ATH_MSG_VERBOSE("Depletion depth: " << depletionDepth/CLHEP::mm);
181  ATH_MSG_VERBOSE("Mobility (cm2/V/s): " << mobility/(CLHEP::cm2/CLHEP::volt/CLHEP::s));
182  ATH_MSG_VERBOSE("Magnetic Field (tesla): " << "(" << magneticField.x()/CLHEP::tesla << "," << magneticField.y()/CLHEP::tesla << "," << magneticField.z()/CLHEP::tesla << ")");
183  ATH_MSG_VERBOSE("LorentzShift, tanLorentzAngle = " << writeCdo->getLorentzShift(elementHash) << ", " << writeCdo->getTanLorentzAngle(elementHash));
184  ATH_MSG_VERBOSE("LorentzShiftEta, tanLorentzAngleEta = " << writeCdo->getLorentzShiftEta(elementHash) << ", " << writeCdo->getTanLorentzAngleEta(elementHash));
185  }
186 
187  // Record the output cond object
188  if (writeHandle.record(std::move(writeCdo)).isFailure()) {
189  ATH_MSG_FATAL("Could not record SiLorentzAngleCondData " << writeHandle.key() << " with EventRange " << writeHandle.getRange() << " into Conditions Store");
190  return StatusCode::FAILURE;
191  }
192 
193  ATH_MSG_DEBUG("recorded new CDO " << writeHandle.key() << " with range " << writeHandle.getRange() << " into Conditions Store");
194 
195  return StatusCode::SUCCESS;
196 }
197 
199  ATH_MSG_DEBUG("PixelSiLorentzAngleCondAlg::finalize()");
200  return StatusCode::SUCCESS;
201 }
202 
204  if (m_useMagFieldCache) {
205  ATH_MSG_VERBOSE("Getting magnetic field from MT magnetic field service.");
206  double field[3]; //in/out parameter
207  fieldCache.getField(element->center().data(), field);
208  return Amg::Vector3D(field[0], field[1], field[2]);
209  }
210  else {
211  ATH_MSG_VERBOSE("Using Nominal Field");
212  return Amg::Vector3D(0., 0., m_nominalField);
213  }
214 }
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
PixelID.h
This is an Identifier helper class for the Pixel subdetector. This class is a factory for creating co...
PixelSiLorentzAngleCondAlg::m_useMagFieldCache
BooleanProperty m_useMagFieldCache
Definition: PixelSiLorentzAngleCondAlg.h:69
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
PixelSiLorentzAngleCondAlg::execute
virtual StatusCode execute(const EventContext &ctx) const override
Definition: PixelSiLorentzAngleCondAlg.cxx:45
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
SG::ReadCondHandle::getRange
const EventIDRange & getRange()
Definition: ReadCondHandle.h:242
SG::ReadCondHandle::fullKey
const DataObjID & fullKey() const
Definition: ReadCondHandle.h:60
InDetDD::SiDetectorElementCollection
Definition: SiDetectorElementCollection.h:30
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
InDetDD::PixelModuleDesign
Definition: PixelModuleDesign.h:48
AtlasFieldCacheCondObj
Definition: AtlasFieldCacheCondObj.h:19
InDetDD::SolidStateDetectorElementBase::hitEtaDirection
double hitEtaDirection() const
See previous method.
PixelSiLorentzAngleCondAlg::m_readKeyTemp
SG::ReadCondHandleKey< PixelDCSTempData > m_readKeyTemp
Definition: PixelSiLorentzAngleCondAlg.h:50
InDetDD::SolidStateDetectorElementBase::center
virtual const Amg::Vector3D & center() const override final
Center in global coordinates.
InDetDD::SolidStateDetectorElementBase::etaAxis
const Amg::Vector3D & etaAxis() const
Definition: SolidStateDetectorElementBase.cxx:88
PixelSiLorentzAngleCondAlg::m_pixelIDName
Gaudi::Property< std::string > m_pixelIDName
Definition: PixelSiLorentzAngleCondAlg.h:46
InDetDD::SolidStateDetectorElementBase::hitPhiDirection
double hitPhiDirection() const
See previous method.
InDetDD::DetectorDesign::readoutSide
int readoutSide() const
ReadoutSide.
Definition: DetectorDesign.h:291
IdentifierHash::value_type
unsigned int value_type
Definition: IdentifierHash.h:27
ReadOfcFromCool.field
field
Definition: ReadOfcFromCool.py:48
PixelDCSTempData
Definition: PixelDCSTempData.h:19
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
SG::VarHandleKey::key
const std::string & key() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:141
CondAttrListCollection
This class is a collection of AttributeLists where each one is associated with a channel number....
Definition: CondAttrListCollection.h:52
PixelDCSHVData
Definition: PixelDCSHVData.h:19
AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::detStore
const ServiceHandle< StoreGateSvc > & detStore() const
The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:95
AthReentrantAlgorithm
An algorithm that can be simultaneously executed in multiple threads.
Definition: AthReentrantAlgorithm.h:83
InDetDD::SolidStateDetectorElementBase::hitDepthDirection
double hitDepthDirection() const
Directions of hit depth,phi,eta axes relative to reconstruction local position axes (LocalPosition).
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
SG::ReadCondHandle::retrieve
const_pointer_type retrieve()
Definition: ReadCondHandle.h:162
python.SystemOfUnits.cm2
int cm2
Definition: SystemOfUnits.py:88
InDetDD::SolidStateDetectorElementBase::thickness
double thickness() const
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
PixelSiLorentzAngleCondAlg::m_siPropertiesTool
ToolHandle< ISiPropertiesTool > m_siPropertiesTool
Definition: PixelSiLorentzAngleCondAlg.h:65
PixelSiLorentzAngleCondAlg.h
PixelSiLorentzAngleCondAlg::m_pixelDetEleCollKey
SG::ReadCondHandleKey< InDetDD::SiDetectorElementCollection > m_pixelDetEleCollKey
Definition: PixelSiLorentzAngleCondAlg.h:59
python.SystemOfUnits.volt
int volt
Definition: SystemOfUnits.py:204
InDetDD::SolidStateDetectorElementBase::normal
virtual const Amg::Vector3D & normal() const override final
Get reconstruction local normal axes in global frame.
dot.dot
def dot(G, fn, nodesToHighlight=[])
Definition: dot.py:5
PixelSiLorentzAngleCondAlg::m_maxHash
unsigned int m_maxHash
Definition: PixelSiLorentzAngleCondAlg.h:73
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
python.SystemOfUnits.tesla
int tesla
Definition: SystemOfUnits.py:228
InDetDD::SiDetectorElement
Definition: SiDetectorElement.h:109
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
InDetDD::PixelReadoutTechnology::FEI4
@ FEI4
InDet::SiliconProperties
Definition: SiliconProperties.h:24
InDet::SiliconProperties::signedHallMobility
double signedHallMobility(InDetDD::CarrierType carrier) const
Definition: SiliconProperties.cxx:114
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
SiDetectorElement.h
PixelSiLorentzAngleCondAlg::m_readKeyBFieldSensor
SG::ReadCondHandleKey< CondAttrListCollection > m_readKeyBFieldSensor
Definition: PixelSiLorentzAngleCondAlg.h:56
PixelSiLorentzAngleCondAlg::m_fieldCondObjInputKey
SG::ReadCondHandleKey< AtlasFieldCacheCondObj > m_fieldCondObjInputKey
Definition: PixelSiLorentzAngleCondAlg.h:80
python.SystemOfUnits.mm
int mm
Definition: SystemOfUnits.py:83
CaloCondBlobAlgs_fillNoiseFromASCII.hash
dictionary hash
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:109
PixelModuleDesign.h
PixelSiLorentzAngleCondAlg::m_nominalField
DoubleProperty m_nominalField
Definition: PixelSiLorentzAngleCondAlg.h:68
InDetDD::SolidStateDetectorElementBase::phiAxis
const Amg::Vector3D & phiAxis() const
Definition: SolidStateDetectorElementBase.cxx:74
PixelDCSHVData::getBiasVoltage
float getBiasVoltage(const int chanNum) const
Definition: PixelDCSHVData.cxx:11
MagField::AtlasFieldCache
Local cache for magnetic field (based on MagFieldServices/AtlasFieldSvcTLS.h)
Definition: AtlasFieldCache.h:43
MagField::AtlasFieldCache::getField
void getField(const double *ATH_RESTRICT xyz, double *ATH_RESTRICT bxyz, double *ATH_RESTRICT deriv=nullptr)
get B field value at given position xyz[3] is in mm, bxyz[3] is in kT if deriv[9] is given,...
Definition: AtlasFieldCache.cxx:42
PixelSiLorentzAngleCondAlg::m_useMagFieldDcs
BooleanProperty m_useMagFieldDcs
Definition: PixelSiLorentzAngleCondAlg.h:70
InDetDD::SiDetectorElement::carrierType
InDetDD::CarrierType carrierType() const
carrier type for readout.
PixelSiLorentzAngleCondAlg::PixelSiLorentzAngleCondAlg
PixelSiLorentzAngleCondAlg(const std::string &name, ISvcLocator *pSvcLocator)
Definition: PixelSiLorentzAngleCondAlg.cxx:14
PixelID::size_type
Identifier::size_type size_type
Definition: PixelID.h:71
PixelSiLorentzAngleCondAlg::m_readKeyHV
SG::ReadCondHandleKey< PixelDCSHVData > m_readKeyHV
Definition: PixelSiLorentzAngleCondAlg.h:53
IdentifierHash
This is a "hash" representation of an Identifier. This encodes a 32 bit index which can be used to lo...
Definition: IdentifierHash.h:25
InDetDD::SiDetectorElement::design
virtual const SiDetectorDesign & design() const override final
access to the local description (inline):
PixelSiLorentzAngleCondAlg::initialize
virtual StatusCode initialize() override
Definition: PixelSiLorentzAngleCondAlg.cxx:19
PixelID
Definition: PixelID.h:67
PixelSiLorentzAngleCondAlg::m_disable3D
BooleanProperty m_disable3D
Definition: PixelSiLorentzAngleCondAlg.h:71
PixelSiLorentzAngleCondAlg::finalize
virtual StatusCode finalize() override
Definition: PixelSiLorentzAngleCondAlg.cxx:198
SG::WriteCondHandle
Definition: WriteCondHandle.h:26
InDetDD::SiDetectorElementCollection::getDetectorElement
const SiDetectorElement * getDetectorElement(const IdentifierHash &hash) const
Definition: SiDetectorElementCollection.cxx:15
PixelSiLorentzAngleCondAlg::getMagneticField
Amg::Vector3D getMagneticField(MagField::AtlasFieldCache &m_fieldCache, const InDetDD::SiDetectorElement *element) const
Definition: PixelSiLorentzAngleCondAlg.cxx:203
SiliconProperties.h
PixelSiLorentzAngleCondAlg::m_writeKey
SG::WriteCondHandleKey< SiLorentzAngleCondData > m_writeKey
Definition: PixelSiLorentzAngleCondAlg.h:62
PixelDCSTempData::getTemperature
float getTemperature(const int chanNum) const
Definition: PixelDCSTemp.cxx:11