22#include "GaudiKernel/PhysicalConstants.h"
24#include "CoralBase/Attribute.h"
25#include "CoralBase/AttributeListSpecification.h"
26#include "CoralBase/Blob.h"
29#include <unordered_map>
41#define SET_BRANCHADDRESS(tree, branchName) \
43 if (!tree.GetBranch(#branchName)) { \
44 ATH_MSG_FATAL("The branch "<<#branchName<<" does not exist."); \
45 return StatusCode::FAILURE; \
47 if (tree.SetBranchAddress(#branchName,&branchName) != 0){ \
48 ATH_MSG_FATAL("Failed to connect branch "<<#branchName<<"."); \
49 return StatusCode::FAILURE; \
75 }
else if (
m_rtJSON.value().size()) {
84 }
else if (
m_t0JSON.value().size()) {
88 return StatusCode::SUCCESS;
96 return StatusCode::SUCCESS;
99 auto writeCdo = std::make_unique<MdtCalibDataContainer>(
m_idHelperSvc.get(), RegionGranularity::OnePerMultiLayer);
101 writeCdo->setInversePropSpeed(1./ (
m_prop_beta * Gaudi::Units::c_light));
109 itr != readHandle->end(); ++itr) {
110 const coral::AttributeList& atr = itr->second;
111 if(atr[
"data"].specification().
type() !=
typeid(coral::Blob)) {
113 return StatusCode::FAILURE;
116 coral::Blob blob = atr[
"data"].data<coral::Blob>();
119 std::unique_ptr<TTree>
tree;
122 return StatusCode::FAILURE;
130 return StatusCode::FAILURE;
132 nlohmann::json rtBlob = nlohmann::json::parse(
data);
136 return StatusCode::FAILURE;
141 std::unique_ptr<TFile> inFile{TFile::Open(
m_rtRootFile.value().c_str(),
"READ")};
142 if(!inFile || inFile->IsZombie()) {
144 return StatusCode::FAILURE;
146 TTree*
tree{
nullptr};
150 return StatusCode::FAILURE;
153 }
else if (!
m_rtJSON.value().empty()) {
155 if (!inFile.good()) {
157 return StatusCode::FAILURE;
159 nlohmann::json rtBlob{};
168 itr != readHandle->end(); ++itr) {
169 const coral::AttributeList& atr = itr->second;
170 if(atr[
"data"].specification().
type() !=
typeid(coral::Blob)) {
172 return StatusCode::FAILURE;
175 coral::Blob blob = atr[
"data"].data<coral::Blob>();
178 std::unique_ptr<TTree>
tree;
181 return StatusCode::FAILURE;
189 return StatusCode::FAILURE;
191 nlohmann::json rtBlob = nlohmann::json::parse(
data);
195 return StatusCode::FAILURE;
200 std::unique_ptr<TFile> inFile{TFile::Open(
m_t0RootFile.value().c_str(),
"READ")};
201 if(!inFile || inFile->IsZombie()) {
203 return StatusCode::FAILURE;
205 TTree*
tree{
nullptr};
209 return StatusCode::FAILURE;
214 if (!inFile.good()) {
216 return StatusCode::FAILURE;
218 nlohmann::json t0Blob{};
225 return StatusCode::SUCCESS;
233 std::string* rtType{
nullptr}, *trType{
nullptr}, *resoType{
nullptr};
235 std::vector<double>* rtParams{
nullptr}, *trParams{
nullptr}, *resoParams{
nullptr};
237 std::vector<std::string>* stationName{
nullptr};
238 std::vector<short>* stationEta{
nullptr};
239 std::vector<unsigned short>* stationPhi{
nullptr}, *multiLayer{
nullptr};
252 for (Long64_t e = 0; e< rtTree.GetEntries(); ++e) {
254 ATH_MSG_VERBOSE(
"Load "<<e<<
"-th calibration constant Valid for "<<stationName->size()<<
" det elements.");
255 std::vector<Identifier> detIds{};
256 for (
unsigned ch = 0; ch < stationName->size(); ++ch){
257 const Identifier detElId = idHelper.
channelID(stationName->at(ch), stationEta->at(ch), stationPhi->at(ch),
258 multiLayer->at(ch), 1, 1);
259 detIds.emplace_back(detElId);
263 return StatusCode::FAILURE;
266 if ((*trType).size() && !trRel) {
267 return StatusCode::FAILURE;
271 return StatusCode::FAILURE;
274 std::make_unique<MdtRtRelation>(std::move(rtRel), std::move(rtReso), std::move(trRel));
276 if (!outContainer.
storeData(detId, mdtRel, msgStream())){
277 return StatusCode::FAILURE;
281 return StatusCode::SUCCESS;
285 if (rtType ==
"RtRelationLookUp") {
286 rtRel = std::make_unique<RtRelationLookUp>(rtParams);
287 }
else if (rtType ==
"RtLegendre"){
288 rtRel = std::make_unique<RtLegendre>(rtParams);
289 }
else if (rtType ==
"RtChebyshev") {
290 rtRel = std::make_unique<RtChebyshev>(rtParams);
293 ATH_MSG_VERBOSE(
"Fetched new rt-relation <"<<rtType<<
"> valid for drift times ranging from "
296 ATH_MSG_FATAL(
"The rt-relation function type <"<<rtType<<
"> is not yet supported.");
303 if (trType ==
"TrChebyshev") {
304 trRel = std::make_unique<TrChebyshev>(trParams);
305 }
else if(trType ==
"TrLegendre") {
306 trRel = std::make_unique<TrLegendre>(trParams);
309 ATH_MSG_VERBOSE(
"Fetched new tr-relation <"<<trType<<
"> valid for drift radii ranging from "
312 ATH_MSG_FATAL(
"The rt-relation function type <"<<trType<<
"> is not yet supported.");
320 if (resoType ==
"RtResolutionLookUp") {
321 rtReso = std::make_unique<RtResolutionLookUp>(resoParams);
322 }
else if (resoType ==
"RtResolutionChebyshev") {
323 rtReso = std::make_unique<RtResolutionChebyshev>(resoParams);
324 }
else if (resoType ==
"RadiusResolutionChebyshev") {
325 rtReso = std::make_unique<RadiusResolutionChebyshev>(resoParams, rt);
327 ATH_MSG_FATAL(
"The rt resolution type <"<<resoType<<
"> is not yet supported.");
336 for (
auto& payload : rtBlob.items()) {
337 std::vector<Identifier> detIds{};
339 const nlohmann::json calibConstants = payload.value();
341 for (
auto& chambList : calibConstants[
"chambers"].items()) {
342 const nlohmann::json chambPayload = chambList.value();
343 const std::string station = chambPayload[
"station"];
344 const int eta = chambPayload[
"eta"];
345 const int phi = chambPayload[
"phi"];
346 const int ml = chambPayload[
"ml"];
348 detIds.emplace_back(mlId);
352 const nlohmann::json rtPayload = calibConstants[
"rtRelation"];
356 return StatusCode::FAILURE;
358 if (calibConstants.find(
"trRelation") != calibConstants.end()) {
359 const nlohmann::json trPayload = calibConstants[
"trRelation"];
360 trRel =
makeTr(trPayload[
"type"], trPayload[
"params"]);
362 return StatusCode::FAILURE;
366 const nlohmann::json resoPayload = calibConstants[
"rtReso"];
369 return StatusCode::FAILURE;
372 std::make_unique<MdtRtRelation>(std::move(rtRel), std::move(rtReso), std::move(trRel));
378 outContainer.
getCalibData(mlId, msgStream())->rtRelation) {
381 if (!outContainer.
storeData(mlId, mdtRel, msgStream())) {
382 return StatusCode::FAILURE;
386 return StatusCode::SUCCESS;
392 std::string* stationName{
nullptr};
394 unsigned short stationPhi{0}, code{0};
395 float t0{0.f}, adc{0.f};
396 std::vector<unsigned short>* multiLayer{
nullptr}, *tubeLayer{
nullptr}, *tube{
nullptr};
411 for (Long64_t e = 0 ; e <t0Tree.GetEntries(); ++e) {
416 ATH_MSG_FATAL(
"Failed to create a valid Identifier from "<<(*stationName)<<
", "<<stationEta<<
", "
418 return StatusCode::FAILURE;
426 for (
unsigned int ch = 0; ch < multiLayer->size(); ++ch){
428 tubeLayer->at(ch), tube->at(ch),
isValid)};
431 <<
", ml: "<<multiLayer->at(ch)<<
", tl: "<<tubeLayer->at(ch)<<
", tube: "<<tube->at(ch));
432 return StatusCode::FAILURE;
434 if (!calibChannels->
setCalib(t0Calib, tubeId, msgStream())) {
435 return StatusCode::FAILURE;
438 if (!outContainer.
storeData(detId, calibChannels, msgStream())){
439 return StatusCode::FAILURE;
442 return StatusCode::SUCCESS;
450 for (
auto& dbEntry : t0Blob.items()) {
451 const nlohmann::json payload = dbEntry.value();
452 const std::string station = payload[
"station"];
453 const int eta = payload[
"eta"];
454 const int phi = payload[
"phi"];
459 return StatusCode::FAILURE;
463 for (
auto& calibEntry : payload[
"calibConstants"].items()){
464 const nlohmann::json calibPayload = calibEntry.value();
466 calibConstant.
t0 = calibPayload[
"t0"];
467 calibConstant.
adcCal = calibPayload[
"adc"];
468 calibConstant.
statusCode = calibPayload[
"code"];
469 for (
auto& tubeEntry : calibPayload[
"tubes"].items()) {
470 const nlohmann::json tubePayload = tubeEntry.value();
471 const int ml = tubePayload[
"ml"];
472 const int tubeLayer = tubePayload[
"tl"];
473 const std::string tubeStr = tubePayload[
"no"];
475 std::vector<int> tubes{};
476 for (
const std::string& token: tubeTokens) {
477 if (token.find(
"-") == std::string::npos) {
481 if (rangeToken.size() != 2) {
483 return StatusCode::FAILURE;
486 if (tubeLow >= tubeHigh){
488 <<
". The lower end must be strictly smaller than the upper one");
489 return StatusCode::FAILURE;
491 for (
int tube = tubeLow; tube<=tubeHigh; ++tube) {
492 tubes.push_back(tube);
496 for (
const int tube : tubes) {
500 <<
", layer: "<<tubeLayer<<
", tube: "<<tube);
501 return StatusCode::FAILURE;
503 if (!calibChannels->
setCalib(calibConstant, tubeId, msgStream())){
504 return StatusCode::FAILURE;
509 if (!outContainer.
storeData(detId, std::move(calibChannels), msgStream())) {
510 return StatusCode::FAILURE;
514 return StatusCode::SUCCESS;
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
bool isValid(const T &p)
Av: we implement here an ATLAS-sepcific convention: all particles which are 99xxxxx are fine.
char data[hepevt_bytes_allocation_ATLAS]
MdtCalibDataContainer::RegionGranularity RegionGranularity
#define SET_BRANCHADDRESS(tree, branchName)
ChanAttrListMap::const_iterator const_iterator
static EventIDRange infiniteRunLB()
Produces an EventIDRange that is infinite in RunLumi and invalid in Time.
Identifier elementID(int stationName, int stationEta, int stationPhi) const
Identifier channelID(int stationName, int stationEta, int stationPhi, int multilayer, int tubeLayer, int tube) const
StatusCode parseRtPayload(const nlohmann::json &rtBlob, MuonCalib::MdtCalibDataContainer &outContainer) const
MuonCalib::IRtRelationPtr makeRt(const std::string &rtType, const std::vector< double > &pars) const
Creates a new rt function from the typeName & the list of parameters.
Gaudi::Property< std::string > m_dbPayloadType
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
StatusCode parseT0Payload(const nlohmann::json &t0Blob, MuonCalib::MdtCalibDataContainer &outContainer) const
Trnaslates a t0 - JSON payload into transient memory.
Gaudi::Property< std::string > m_rtRootFile
SG::ReadCondHandleKey< CondAttrListCollection > m_readKeyTube
Gaudi::Property< std::string > m_t0TreeName
virtual StatusCode initialize() override
MuonCalib::MdtCalibDataContainer::TubeContainerPtr TubeContainerPtr
SG::WriteCondHandleKey< MuonCalib::MdtCalibDataContainer > m_writeKey
MuonCalib::IRtResolutionPtr makeReso(const std::string &resoType, const std::vector< double > &pars, MuonCalib::IRtRelationPtr rt) const
Creates a new resoltuion function from the typeName & the list of parameters.
Gaudi::Property< std::string > m_rtJSON
External Rt & T0 JSON files.
Gaudi::Property< std::string > m_rtTreeName
MuonCalib::ITrRelationPtr makeTr(const std::string &trType, const std::vector< double > &pars) const
Creates a new tr function from the typeName & the list of parameters.
Gaudi::Property< double > m_prop_beta
Gaudi::Property< std::string > m_t0RootFile
SG::ReadCondHandleKey< CondAttrListCollection > m_readKeyRt
Gaudi::Property< std::string > m_t0JSON
virtual StatusCode execute(const EventContext &ctx) const override
virtual double tLower() const =0
Returns the lower time covered by the r-t.
virtual double tUpper() const =0
Returns the upper time covered by the r-t.
virtual double maxRadius() const =0
Returns the maximum drift-radius.
virtual double minRadius() const =0
Returns the minimum drift-radius.
bool storeData(const Identifier &mlID, CorrectionPtr corrFuncSet, MsgStream &msg)
bool hasDataForChannel(const Identifier &measId, MsgStream &msg) const
Checks whether a calibration data object is already present.
const MdtFullCalibData * getCalibData(const Identifier &measId, MsgStream &msg) const
Returns the calibration data associated with this station.
bool setCalib(SingleTubeCalib val, const Identifier &tubeId, MsgStream &msg)
set the calibration constants of a single tube
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
bool readBlobAsString(const coral::Blob &, std::string &)
bool readBlobAsTTree(const coral::Blob &blob, std::unique_ptr< TTree > &tree, const std::string_view name="tree")
Interprets the coral::Blob as a TTree instance.
std::vector< std::string > tokenize(const std::string &the_str, std::string_view delimiters)
Splits the string into smaller substrings.
int atoi(std::string_view str)
Helper functions to unpack numbers decoded in string into integers and doubles The strings are requir...
CscCalcPed - algorithm that finds the Cathode Strip Chamber pedestals from an RDO.
GeoModel::TransientConstSharedPtr< IRtRelation > IRtRelationPtr
GeoModel::TransientConstSharedPtr< ITrRelation > ITrRelationPtr
GeoModel::TransientConstSharedPtr< IRtResolution > IRtResolutionPtr
GeoModel::TransientConstSharedPtr< MdtRtRelation > RtRelationPtr
float adcCal
quality flag for the SingleTubeCalib constants: 0 all ok, 1 no hits found, 2 too few hits,...
float t0
< relative t0 in chamber (ns)