ATLAS Offline Software
Loading...
Searching...
No Matches
SCT_ConditionsParameterCondAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
6
10
11#include <memory>
12
13namespace { //anonymous namespace introduces file-scoped functions
14 //is the value 'Not-a-Number' ?
15 template <typename T>
16 bool is_nan(const T& val) {
17 return val!=val; //NaN is only value for which this is true
18 }
19 //response curve fit possibilities
20 enum ResponseCurveFit{NO_CURVE=0, POLYNOMIAL, GRILLO, EXPONENTIAL, LINEAR, N_FUNCS}; //'Grillo' refers to Alex Grillo, Santa Cruz, who worked on SCT electronics development
21 //response curve fit function
22 float responseCurve(const float param0, const float param1, const float param2, const float vthreshold, const unsigned int rcFunc) {
23 float result{std::numeric_limits<float>::quiet_NaN()};
24 switch (rcFunc) {
25 case LINEAR:
26 if (param1!=0.0) {
27 result = (vthreshold - param0)/param1;
28 }
29 break;
30 case EXPONENTIAL:
31 if ((vthreshold - param2)!=0) {
32 float err2{param0/(vthreshold-param2)-1.0f};
33 if (err2 > 0.0) {
34 result = -param1*std::log(err2);
35 }
36 }
37 break;
38 case GRILLO:
39 if (param2!=0) {
40 float err3{param1*(1.0f-((vthreshold-param0)/param2))};
41 if (err3!=0) {
42 result = (vthreshold-param0)/err3;
43 }
44 }
45 break;
46 case POLYNOMIAL:
47 if (param2!=0) {
48 result = (-param1 + std::sqrt((param1*param1)-(4.0*param2*(param0-vthreshold)))) / 2.0*param2;
49 }
50 break;
51 default:
52 //nop
53 break;
54 }//switch
55 if (is_nan(result)) return result;
56 result *= result;
57 return result;
58 }//func responseCurve
59
60 void parseResponseCurveArguments(float* p, const std::string& arguments) {
61 //string is of form:
62 //p0 1.284730e+03 p1 5.830000e+00 p2 -5.989900e+02
63 float* p0{&p[0]};
64 float* p1{&p[1]};
65 float* p2{&p[2]};
66 std::sscanf(arguments.c_str(), "p0 %50e p1 %50e p2 %50e", p0, p1, p2);
67 }
68 //folder to retrieve for threshold parameters
69 const std::string chipFolderName{"/SCT/DAQ/Configuration/Chip"}; //CoraCool folder in the DB
70}//namespace
71
72SCT_ConditionsParameterCondAlg::SCT_ConditionsParameterCondAlg(const std::string& name, ISvcLocator* pSvcLocator)
73 : ::AthCondAlgorithm(name, pSvcLocator)
74{
75}
76
78 ATH_MSG_DEBUG("initialize " << name());
79
80 // Cabling tool
81 ATH_CHECK(m_cablingTool.retrieve());
82 // Read Cond Handle
83 ATH_CHECK(m_readKey.initialize());
84 // Write Cond Handle
85 ATH_CHECK(m_writeKey.initialize());
86
87 return StatusCode::SUCCESS;
88}
89
90StatusCode SCT_ConditionsParameterCondAlg::execute(const EventContext& ctx) const {
91 ATH_MSG_DEBUG("execute " << name());
92
93 // Write Cond Handle
95 // Do we have a valid Write Cond Handle for current time?
96 if (writeHandle.isValid()) {
97 ATH_MSG_DEBUG("CondHandle " << writeHandle.fullKey() << " is already valid."
98 << ". In theory this should not be called, but may happen"
99 << " if multiple concurrent events are being processed out of order.");
100 return StatusCode::SUCCESS;
101 }
102
103 // Read Cond Handle
105 const CondAttrListVec* readCdo{*readHandle};
106 if (readCdo==nullptr) {
107 ATH_MSG_FATAL("Null pointer to the read conditions object");
108 return StatusCode::FAILURE;
109 }
110 // Add dependency
111 writeHandle.addDependency(readHandle);
112 ATH_MSG_INFO("Size of CondAttrListVec " << readHandle.fullKey() << " readCdo->size()= " << readCdo->size());
113 ATH_MSG_INFO("Range of input is " << readHandle.getRange());
114
115 // Construct the output Cond Object and fill it in
116 std::unique_ptr<SCT_CondParameterData> writeCdo{std::make_unique<SCT_CondParameterData>()};
117
118 // Loop over elements (i.e groups of 6 chips) in DB folder
119 static const unsigned int nChipsPerModule{12};
120 static const unsigned int nChipsPerSide{6};
121 static const float mVperDacBit{2.5};
122 CondAttrListVec::const_iterator modItr{readCdo->begin()};
123 CondAttrListVec::const_iterator modEnd{readCdo->end()};
124 for (; modItr != modEnd; modItr += nChipsPerModule) {
125 // Get SN and identifiers (the channel number is serial number+1)
126 const unsigned int truncatedSerialNumber{modItr->first - 1};
127 const IdentifierHash& moduleHash{m_cablingTool->getHashFromSerialNumber(truncatedSerialNumber, ctx)};
128 if (not moduleHash.is_valid()) continue;
129 // Loop over chips within module
130
131 for (unsigned int side{0}; side!=2; ++side) {
132 IdentifierHash elementHash{moduleHash + side};
133 CondAttrListVec::const_iterator channelItr{modItr};
134 CondAttrListVec::const_iterator channelEnd{modItr + nChipsPerSide};
135 std::vector<SCT_Chip*> chipsInMod;
136 chipsInMod.reserve(nChipsPerSide);
137 float parameters[3]{0.0, 0.0, 0.0};
138 float chipsum{0.0};
139 for (; channelItr != channelEnd; ++channelItr) {
140 // Can get AttributeList from second (see https://svnweb.cern.ch/trac/lcgcoral/browser/coral/trunk/src/CoralBase/CoralBase/AttributeList.h )
141 //short id = channelItr->second[2].data<short>(); //chip 0-11
142 float vthr{mVperDacBit * channelItr->second[10].data<short>()}; //threshold setting
143 short rcFunctionIndex{channelItr->second[15].data<short>()}; //response curve function
144 const std::string &rcArgumentString{channelItr->second[16].data<std::string>()}; //response curve arguments
145 parseResponseCurveArguments(parameters, rcArgumentString);
146 //float target = channelItr->second[18].data<float>(); //trim target...use for debugging only
147 float femtoCoulombThreshold{responseCurve(parameters[0], parameters[1], parameters[2], vthr, rcFunctionIndex)};
148 chipsum+=femtoCoulombThreshold;
149 }
150 float moduleAverage{chipsum/nChipsPerSide};
151 writeCdo->setValue(elementHash, SCT_CondParameterData::AVG_THRESHOLD, moduleAverage);
152 }//side loop
153 }//module loop
154
155 // Record the output cond object
156 if (writeHandle.record(std::move(writeCdo)).isFailure()) {
157 ATH_MSG_FATAL("Could not record SCT_CondParameterData " << writeHandle.key()
158 << " with EventRange " << writeHandle.getRange()
159 << " into Conditions Store");
160 return StatusCode::FAILURE;
161 }
162 ATH_MSG_INFO("recorded new CDO " << writeHandle.key() << " with range " << writeHandle.getRange() << " into Conditions Store");
163
164 return StatusCode::SUCCESS;
165}
166
168{
169 ATH_MSG_DEBUG("finalize " << name());
170 return StatusCode::SUCCESS;
171}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_DEBUG(x)
A CondAttrListVec is an Athena DataObject holding a vector of CORAL AttributeLists,...
Header file storing infomration on the SCT chips: id, config, mask.
Base class for conditions algorithms.
AttrListVec::const_iterator const_iterator
const_iterator end() const
const_iterator begin() const
size_type size() const
This is a "hash" representation of an Identifier.
bool is_valid() const
Check if id is in a valid state.
SG::WriteCondHandleKey< SCT_CondParameterData > m_writeKey
virtual StatusCode execute(const EventContext &ctx) const override final
virtual StatusCode initialize() override final
virtual StatusCode finalize() override final
SG::ReadCondHandleKey< CondAttrListVec > m_readKey
SCT_ConditionsParameterCondAlg(const std::string &name, ISvcLocator *pSvcLocator)
ToolHandle< ISCT_CablingTool > m_cablingTool
const DataObjID & fullKey() const
const EventIDRange & getRange()
const std::string & key() const
void addDependency(const EventIDRange &range)
const EventIDRange & getRange() const
StatusCode record(const EventIDRange &range, T *t)
record handle, with explicit range DEPRECATED
const DataObjID & fullKey() const