Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 11:56:36

0001 /*** Header file ***/
0002 #include "Alignment/MillePedeAlignmentAlgorithm/interface/MillePedeFileReader.h"
0003 #include "Alignment/CommonAlignment/interface/AlignableObjectId.h"
0004 
0005 /*** system includes ***/
0006 #include <cmath>  // include floating-point std::abs functions
0007 #include <fstream>
0008 
0009 /*** Alignment ***/
0010 #include "Alignment/TrackerAlignment/interface/AlignableTracker.h"
0011 
0012 //=============================================================================
0013 //===   PUBLIC METHOD IMPLEMENTATION                                        ===
0014 //=============================================================================
0015 
0016 MillePedeFileReader ::MillePedeFileReader(const edm::ParameterSet& config,
0017                                           const std::shared_ptr<const PedeLabelerBase>& pedeLabeler,
0018                                           const std::shared_ptr<const AlignPCLThresholdsHG>& theThresholds,
0019                                           const std::shared_ptr<const PixelTopologyMap>& pixelTopologyMap)
0020     : pedeLabeler_(pedeLabeler),
0021       theThresholds_(theThresholds),
0022       pixelTopologyMap_(pixelTopologyMap),
0023       dirName_(config.getParameter<std::string>("fileDir")),
0024       millePedeEndFile_(config.getParameter<std::string>("millePedeEndFile")),
0025       millePedeLogFile_(config.getParameter<std::string>("millePedeLogFile")),
0026       millePedeResFile_(config.getParameter<std::string>("millePedeResFile")),
0027       isHG_(config.getParameter<bool>("isHG")) {
0028   if (!dirName_.empty() && dirName_.find_last_of('/') != dirName_.size() - 1)
0029     dirName_ += '/';  // may need '/'
0030 }
0031 
0032 void MillePedeFileReader ::read() {
0033   if (isHG_) {
0034     initializeIndexHelper();
0035   }
0036   readMillePedeEndFile();
0037   readMillePedeLogFile();
0038   readMillePedeResultFile();
0039 }
0040 
0041 bool MillePedeFileReader ::storeAlignments() { return (updateDB_ && !vetoUpdateDB_); }
0042 
0043 //=============================================================================
0044 //===   PRIVATE METHOD IMPLEMENTATION                                       ===
0045 //=============================================================================
0046 void MillePedeFileReader ::readMillePedeEndFile() {
0047   std::ifstream endFile;
0048   endFile.open((dirName_ + millePedeEndFile_).c_str());
0049 
0050   if (endFile.is_open()) {
0051     edm::LogInfo("MillePedeFileReader") << "Reading millepede end-file";
0052     std::string line;
0053     getline(endFile, line);
0054     std::string trash;
0055     if (line.find("-1") != std::string::npos) {
0056       getline(endFile, line);
0057       exitMessage_ = line;
0058       std::istringstream iss(line);
0059       iss >> exitCode_ >> trash;
0060       edm::LogInfo("MillePedeFileReader")
0061           << " Pede exit code is: " << exitCode_ << " (" << exitMessage_ << ")" << std::endl;
0062     } else {
0063       exitMessage_ = line;
0064       std::istringstream iss(line);
0065       iss >> exitCode_ >> trash;
0066       edm::LogInfo("MillePedeFileReader")
0067           << " Pede exit code is: " << exitCode_ << " (" << exitMessage_ << ")" << std::endl;
0068     }
0069   } else {
0070     edm::LogError("MillePedeFileReader") << "Could not read millepede end-file.";
0071     exitMessage_ = "no exit code found";
0072   }
0073 }
0074 
0075 void MillePedeFileReader ::readMillePedeLogFile() {
0076   std::ifstream logFile;
0077   logFile.open((dirName_ + millePedeLogFile_).c_str());
0078 
0079   if (logFile.is_open()) {
0080     edm::LogInfo("MillePedeFileReader") << "Reading millepede log-file";
0081     std::string line;
0082 
0083     while (getline(logFile, line)) {
0084       std::string Nrec_string = "NREC =";
0085       std::string Binaries_string = "C_binary";
0086 
0087       if (line.find(Nrec_string) != std::string::npos) {
0088         std::istringstream iss(line);
0089         std::string trash;
0090         iss >> trash >> trash >> Nrec_;
0091 
0092         if (Nrec_ < theThresholds_->getNrecords()) {
0093           edm::LogInfo("MillePedeFileReader")
0094               << "Number of records used " << theThresholds_->getNrecords() << std::endl;
0095           updateDB_ = false;
0096         }
0097       }
0098 
0099       if (line.find(Binaries_string) != std::string::npos) {
0100         binariesAmount_ += 1;
0101       }
0102     }
0103   } else {
0104     edm::LogError("MillePedeFileReader") << "Could not read millepede log-file.";
0105 
0106     updateDB_ = false;
0107     Nrec_ = 0;
0108   }
0109 }
0110 
0111 void MillePedeFileReader ::readMillePedeResultFile() {
0112   // cutoffs by coordinate and by alignable
0113   std::map<std::string, std::array<float, 6> > cutoffs_;
0114   std::map<std::string, std::array<float, 6> > significances_;
0115   std::map<std::string, std::array<float, 6> > thresholds_;
0116   std::map<std::string, std::array<float, 6> > errors_;
0117   std::map<std::string, std::array<float, 6> > fractions_;
0118 
0119   std::map<std::string, std::array<int, 6> > countsAbove_;
0120   std::map<std::string, std::array<int, 6> > countsTotal_;
0121 
0122   AlignableObjectId alignableObjectId{AlignableObjectId::Geometry::General};
0123 
0124   std::vector<std::string> alignables_ = theThresholds_->getAlignableList();
0125   for (auto& ali : alignables_) {
0126     cutoffs_[ali] = theThresholds_->getCut(ali);
0127     significances_[ali] = theThresholds_->getSigCut(ali);
0128     thresholds_[ali] = theThresholds_->getMaxMoveCut(ali);
0129     errors_[ali] = theThresholds_->getMaxErrorCut(ali);
0130 
0131     if (theThresholds_->hasFloatMap(ali)) {
0132       fractions_[ali] = theThresholds_->getFractionCut(ali);
0133       countsAbove_[ali] = {{0, 0, 0, 0, 0, 0}};
0134       countsTotal_[ali] = {{0, 0, 0, 0, 0, 0}};
0135     }
0136   }
0137 
0138   updateDB_ = false;
0139   vetoUpdateDB_ = false;
0140   std::ifstream resFile;
0141   resFile.open((dirName_ + millePedeResFile_).c_str());
0142 
0143   if (resFile.is_open()) {
0144     edm::LogInfo("MillePedeFileReader") << "Reading millepede result-file";
0145 
0146     std::string line;
0147     getline(resFile, line);  // drop first line
0148 
0149     while (getline(resFile, line)) {
0150       std::istringstream iss(line);
0151 
0152       std::vector<std::string> tokens;
0153       std::string token;
0154       while (iss >> token) {
0155         tokens.push_back(token);
0156       }
0157 
0158       auto alignableLabel = std::stoul(tokens[0]);
0159       const auto alignable = pedeLabeler_->alignableFromLabel(alignableLabel);
0160       auto det = getHLS(alignable);
0161       int detIndex = static_cast<int>(det);
0162       auto alignableIndex = alignableLabel % 10 - 1;
0163       std::string detLabel = getStringFromHLS(det);
0164 
0165       if (tokens.size() > 4 /*3*/) {
0166         countsTotal_[detLabel][alignableIndex]++;  //Count aligned modules/ladders per structure
0167         const auto paramNum = pedeLabeler_->paramNumFromLabel(alignableLabel);
0168         align::StructureType type = alignable->alignableObjectId();
0169         align::ID id = alignable->id();
0170 
0171         double ObsMove = std::stof(tokens[3]) * multiplier_[alignableIndex];
0172         double ObsErr = std::stof(tokens[4]) * multiplier_[alignableIndex];
0173 
0174         auto coord = static_cast<AlignPCLThresholdsHG::coordType>(alignableIndex);
0175 
0176         if (det != PclHLS::NotInPCL) {
0177           if (type != align::TPBLadder && type != align::TPEPanel) {
0178             switch (coord) {
0179               case AlignPCLThresholdsHG::X:
0180                 Xobs_[detIndex] = ObsMove;
0181                 XobsErr_[detIndex] = ObsErr;
0182                 break;
0183               case AlignPCLThresholdsHG::Y:
0184                 Yobs_[detIndex] = ObsMove;
0185                 YobsErr_[detIndex] = ObsErr;
0186                 break;
0187               case AlignPCLThresholdsHG::Z:
0188                 Zobs_[detIndex] = ObsMove;
0189                 ZobsErr_[detIndex] = ObsErr;
0190                 break;
0191               case AlignPCLThresholdsHG::theta_X:
0192                 tXobs_[detIndex] = ObsMove;
0193                 tXobsErr_[detIndex] = ObsErr;
0194                 break;
0195               case AlignPCLThresholdsHG::theta_Y:
0196                 tYobs_[detIndex] = ObsMove;
0197                 tYobsErr_[detIndex] = ObsErr;
0198                 break;
0199               case AlignPCLThresholdsHG::theta_Z:
0200                 tZobs_[detIndex] = ObsMove;
0201                 tZobsErr_[detIndex] = ObsErr;
0202                 break;
0203               default:
0204                 edm::LogError("MillePedeFileReader") << "Currently not able to handle DOF " << coord << std::endl;
0205                 break;
0206             }
0207           } else {
0208             auto hgIndex = getIndexForHG(id, det);
0209             switch (coord) {
0210               case AlignPCLThresholdsHG::X:
0211                 Xobs_HG_[hgIndex - 1] = ObsMove;
0212                 XobsErr_HG_[hgIndex - 1] = ObsErr;
0213                 break;
0214               case AlignPCLThresholdsHG::Y:
0215                 Yobs_HG_[hgIndex - 1] = ObsMove;
0216                 YobsErr_HG_[hgIndex - 1] = ObsErr;
0217                 break;
0218               case AlignPCLThresholdsHG::Z:
0219                 Zobs_HG_[hgIndex - 1] = ObsMove;
0220                 ZobsErr_HG_[hgIndex - 1] = ObsErr;
0221                 break;
0222               case AlignPCLThresholdsHG::theta_X:
0223                 tXobs_HG_[hgIndex - 1] = ObsMove;
0224                 tXobsErr_HG_[hgIndex - 1] = ObsErr;
0225                 break;
0226               case AlignPCLThresholdsHG::theta_Y:
0227                 tYobs_HG_[hgIndex - 1] = ObsMove;
0228                 tYobsErr_HG_[hgIndex - 1] = ObsErr;
0229                 break;
0230               case AlignPCLThresholdsHG::theta_Z:
0231                 tZobs_HG_[hgIndex - 1] = ObsMove;
0232                 tZobsErr_HG_[hgIndex - 1] = ObsErr;
0233                 break;
0234               default:
0235                 edm::LogError("MillePedeFileReader") << "Currently not able to handle DOF " << coord << std::endl;
0236                 break;
0237             }
0238           }
0239 
0240         } else {
0241           edm::LogError("MillePedeFileReader")
0242               << "Currently not able to handle coordinate: " << coord << " (" << paramNum << ")  "
0243               << Form(" %s with ID %d (subdet %d)", alignableObjectId.idToString(type), id, DetId(id).subdetId())
0244               << std::endl;
0245           continue;
0246         }
0247 
0248         edm::LogVerbatim("MillePedeFileReader")
0249             << " alignableLabel: " << alignableLabel << " with alignableIndex " << alignableIndex << " detIndex "
0250             << detIndex << "\n"
0251             << " i.e. detLabel: " << detLabel << " (" << coord << ")\n"
0252             << " has movement: " << ObsMove << " +/- " << ObsErr << "\n"
0253             << " cutoff (cutoffs_[" << detLabel << "][" << coord << "]): " << cutoffs_[detLabel][alignableIndex] << "\n"
0254             << " significance (significances_[" << detLabel << "][" << coord
0255             << "]): " << significances_[detLabel][alignableIndex] << "\n"
0256             << " error thresolds (errors_[" << detLabel << "][" << coord << "]): " << errors_[detLabel][alignableIndex]
0257             << "\n"
0258             << " max movement (thresholds_[" << detLabel << "][" << coord
0259             << "]): " << thresholds_[detLabel][alignableIndex] << "\n"
0260             << " fraction (fractions_[" << detLabel << "][" << coord << "]): " << fractions_[detLabel][alignableIndex]
0261             << "\n"
0262             << "=============" << std::endl;
0263 
0264         if (std::abs(ObsMove) > thresholds_[detLabel][alignableIndex]) {
0265           edm::LogWarning("MillePedeFileReader") << "Aborting payload creation."
0266                                                  << " Exceeding maximum thresholds for movement: " << std::abs(ObsMove)
0267                                                  << " for" << detLabel << "(" << coord << ")";
0268           updateBits_.set(0);
0269           vetoUpdateDB_ = true;
0270           continue;
0271 
0272         } else if (std::abs(ObsMove) > cutoffs_[detLabel][alignableIndex]) {
0273           updateBits_.set(1);
0274 
0275           if (std::abs(ObsErr) > errors_[detLabel][alignableIndex]) {
0276             edm::LogWarning("MillePedeFileReader") << "Aborting payload creation."
0277                                                    << " Exceeding maximum thresholds for error: " << std::abs(ObsErr)
0278                                                    << " for" << detLabel << "(" << coord << ")";
0279             updateBits_.set(2);
0280             vetoUpdateDB_ = true;
0281             continue;
0282           } else {
0283             if (std::abs(ObsMove / ObsErr) < significances_[detLabel][alignableIndex]) {
0284               updateBits_.set(3);
0285               continue;
0286             }
0287           }
0288           updateDB_ = true;
0289           if (!isHG_) {
0290             edm::LogInfo("MillePedeFileReader")
0291                 << "This correction: " << ObsMove << "+/-" << ObsErr << " for " << detLabel << "(" << coord
0292                 << ") will trigger a new Tracker Alignment payload!";
0293           }
0294           countsAbove_[detLabel][alignableIndex]++;
0295         }
0296       }
0297     }
0298   } else {
0299     edm::LogError("MillePedeFileReader") << "Could not read millepede result-file.";
0300 
0301     updateDB_ = false;
0302     Nrec_ = 0;
0303   }
0304 
0305   if (isHG_) {          // check fractionCut
0306     updateDB_ = false;  // reset booleans since fractionCut is considered for HG
0307     std::stringstream ss;
0308     for (auto& ali : alignables_) {
0309       ss << ali << std::endl;
0310       for (long unsigned int i = 0; i < countsTotal_[ali].size(); i++) {
0311         if (countsTotal_[ali][i] != 0 && fractions_[ali][i] != -1) {
0312           float fraction_ = countsAbove_[ali][i] / (1.0 * countsTotal_[ali][i]);
0313           ss << static_cast<AlignPCLThresholdsHG::coordType>(i) << ":   Fraction = " << fraction_
0314              << "   Fraction Threshold = " << fractions_[ali][i];
0315           if (fraction_ >= fractions_[ali][i]) {
0316             updateDB_ = true;
0317             ss << "   above fraction threshold" << std::endl;
0318             fractionExceeded_[ali][i] = true;
0319           } else {
0320             ss << std::endl;
0321             fractionExceeded_[ali][i] = false;
0322           }
0323         } else
0324           ss << "No entries available or no fraction thresholds defined" << std::endl;
0325       }
0326       ss << "===================" << std::endl;
0327     }
0328     if (updateDB_ && !vetoUpdateDB_) {
0329       ss << "Alignment will be updated" << std::endl;
0330     } else {
0331       ss << "Alignment will NOT be updated" << std::endl;
0332     }
0333     edm::LogWarning("MillePedeFileReader") << ss.str();
0334   }
0335 }
0336 
0337 MillePedeFileReader::PclHLS MillePedeFileReader ::getHLS(const Alignable* alignable) {
0338   if (!alignable)
0339     return PclHLS::NotInPCL;
0340 
0341   const auto& tns = pedeLabeler_->alignableTracker()->trackerNameSpace();
0342   const align::ID id = alignable->id();
0343 
0344   switch (alignable->alignableObjectId()) {
0345     case align::TPBHalfBarrel:
0346       switch (tns.tpb().halfBarrelNumber(id)) {
0347         case 1:
0348           return PclHLS::TPBHalfBarrelXminus;
0349         case 2:
0350           return PclHLS::TPBHalfBarrelXplus;
0351         default:
0352           throw cms::Exception("LogicError")
0353               << "@SUB=MillePedeFileReader::getHLS\n"
0354               << "Found a pixel half-barrel number that should not exist: " << tns.tpb().halfBarrelNumber(id);
0355       }
0356     case align::TPEHalfCylinder:
0357       switch (tns.tpe().endcapNumber(id)) {
0358         case 1:
0359           switch (tns.tpe().halfCylinderNumber(id)) {
0360             case 1:
0361               return PclHLS::TPEHalfCylinderXminusZminus;
0362             case 2:
0363               return PclHLS::TPEHalfCylinderXplusZminus;
0364             default:
0365               throw cms::Exception("LogicError")
0366                   << "@SUB=MillePedeFileReader::getHLS\n"
0367                   << "Found a pixel half-cylinder number that should not exist: " << tns.tpe().halfCylinderNumber(id);
0368           }
0369         case 2:
0370           switch (tns.tpe().halfCylinderNumber(id)) {
0371             case 1:
0372               return PclHLS::TPEHalfCylinderXminusZplus;
0373             case 2:
0374               return PclHLS::TPEHalfCylinderXplusZplus;
0375             default:
0376               throw cms::Exception("LogicError")
0377                   << "@SUB=MillePedeFileReader::getHLS\n"
0378                   << "Found a pixel half-cylinder number that should not exist: " << tns.tpe().halfCylinderNumber(id);
0379           }
0380         default:
0381           throw cms::Exception("LogicError")
0382               << "@SUB=MillePedeFileReader::getHLS\n"
0383               << "Found a pixel endcap number that should not exist: " << tns.tpe().endcapNumber(id);
0384       }
0385     case align::TPBLadder:
0386       switch (tns.tpb().layerNumber(id)) {
0387         case 1:
0388           return PclHLS::TPBLadderLayer1;
0389         case 2:
0390           return PclHLS::TPBLadderLayer2;
0391         case 3:
0392           return PclHLS::TPBLadderLayer3;
0393         case 4:
0394           return PclHLS::TPBLadderLayer4;
0395         default:
0396           throw cms::Exception("LogicError")
0397               << "@SUB=MillePedeFileReader::getHLS\n"
0398               << "Found a pixel layer number that should not exist: " << tns.tpb().layerNumber(id);
0399       }
0400     case align::TPEPanel:
0401       switch (static_cast<signed int>((tns.tpe().endcapNumber(id) == 1) ? -1 * tns.tpe().halfDiskNumber(id)
0402                                                                         : tns.tpe().halfDiskNumber(id))) {
0403         case -3:
0404           return PclHLS::TPEPanelDiskM3;
0405         case -2:
0406           return PclHLS::TPEPanelDiskM2;
0407         case -1:
0408           return PclHLS::TPEPanelDiskM1;
0409         case 3:
0410           return PclHLS::TPEPanelDisk3;
0411         case 2:
0412           return PclHLS::TPEPanelDisk2;
0413         case 1:
0414           return PclHLS::TPEPanelDisk1;
0415         default:
0416           throw cms::Exception("LogicError")
0417               << "@SUB=MillePedeFileReader::getHLS\n"
0418               << "Found a pixel disk number that should not exist: "
0419               << static_cast<signed int>((tns.tpe().endcapNumber(id) == 1) ? -1 * tns.tpe().halfDiskNumber(id)
0420                                                                            : tns.tpe().halfDiskNumber(id));
0421       }
0422     default:
0423       return PclHLS::NotInPCL;
0424   }
0425 }
0426 
0427 std::string MillePedeFileReader::getStringFromHLS(MillePedeFileReader::PclHLS HLS) {
0428   switch (HLS) {
0429     case PclHLS::TPBHalfBarrelXminus:
0430       return "TPBHalfBarrelXminus";
0431     case PclHLS::TPBHalfBarrelXplus:
0432       return "TPBHalfBarrelXplus";
0433     case PclHLS::TPEHalfCylinderXminusZminus:
0434       return "TPEHalfCylinderXminusZminus";
0435     case PclHLS::TPEHalfCylinderXplusZminus:
0436       return "TPEHalfCylinderXplusZminus";
0437     case PclHLS::TPEHalfCylinderXminusZplus:
0438       return "TPEHalfCylinderXminusZplus";
0439     case PclHLS::TPEHalfCylinderXplusZplus:
0440       return "TPEHalfCylinderXplusZplus";
0441     case PclHLS::TPBLadderLayer1:
0442       return "TPBLadderLayer1";
0443     case PclHLS::TPBLadderLayer2:
0444       return "TPBLadderLayer2";
0445     case PclHLS::TPBLadderLayer3:
0446       return "TPBLadderLayer3";
0447     case PclHLS::TPBLadderLayer4:
0448       return "TPBLadderLayer4";
0449     case PclHLS::TPEPanelDisk1:
0450       return "TPEPanelDisk1";
0451     case PclHLS::TPEPanelDisk2:
0452       return "TPEPanelDisk2";
0453     case PclHLS::TPEPanelDisk3:
0454       return "TPEPanelDisk3";
0455     case PclHLS::TPEPanelDiskM1:
0456       return "TPEPanelDiskM1";
0457     case PclHLS::TPEPanelDiskM2:
0458       return "TPEPanelDiskM2";
0459     case PclHLS::TPEPanelDiskM3:
0460       return "TPEPanelDiskM3";
0461     default:
0462       //return "NotInPCL";
0463       throw cms::Exception("LogicError")
0464           << "@SUB=MillePedeFileReader::getStringFromHLS\n"
0465           << "Found an alignable structure not possible to map in the default AlignPCLThresholdsHG partitions";
0466   }
0467 }
0468 
0469 void MillePedeFileReader::initializeIndexHelper() {
0470   int currentSum = 0;
0471 
0472   indexHelper[PclHLS::TPBLadderLayer1] =
0473       std::make_pair(currentSum, currentSum + pixelTopologyMap_->getPXBLadders(1) / 2);
0474   currentSum += pixelTopologyMap_->getPXBLadders(1);
0475   indexHelper[PclHLS::TPBLadderLayer2] =
0476       std::make_pair(currentSum, currentSum + pixelTopologyMap_->getPXBLadders(2) / 2);
0477   currentSum += pixelTopologyMap_->getPXBLadders(2);
0478   indexHelper[PclHLS::TPBLadderLayer3] =
0479       std::make_pair(currentSum, currentSum + pixelTopologyMap_->getPXBLadders(3) / 2);
0480   currentSum += pixelTopologyMap_->getPXBLadders(3);
0481   indexHelper[PclHLS::TPBLadderLayer4] =
0482       std::make_pair(currentSum, currentSum + pixelTopologyMap_->getPXBLadders(4) / 2);
0483   currentSum += pixelTopologyMap_->getPXBLadders(4);
0484 
0485   indexHelper[PclHLS::TPEPanelDiskM3] = std::make_pair(currentSum, currentSum + pixelTopologyMap_->getPXFBlades(-3));
0486   currentSum += pixelTopologyMap_->getPXFBlades(-3) * 2;
0487   indexHelper[PclHLS::TPEPanelDiskM2] = std::make_pair(currentSum, currentSum + pixelTopologyMap_->getPXFBlades(-2));
0488   currentSum += pixelTopologyMap_->getPXFBlades(-2) * 2;
0489   indexHelper[PclHLS::TPEPanelDiskM1] = std::make_pair(currentSum, currentSum + pixelTopologyMap_->getPXFBlades(-1));
0490   currentSum += pixelTopologyMap_->getPXFBlades(-1) * 2;
0491 
0492   indexHelper[PclHLS::TPEPanelDisk1] = std::make_pair(currentSum, currentSum + pixelTopologyMap_->getPXFBlades(1));
0493   currentSum += pixelTopologyMap_->getPXFBlades(1) * 2;
0494   indexHelper[PclHLS::TPEPanelDisk2] = std::make_pair(currentSum, currentSum + pixelTopologyMap_->getPXFBlades(2));
0495   currentSum += pixelTopologyMap_->getPXFBlades(2) * 2;
0496   indexHelper[PclHLS::TPEPanelDisk3] = std::make_pair(currentSum, currentSum + pixelTopologyMap_->getPXFBlades(3));
0497 }
0498 
0499 int MillePedeFileReader::getIndexForHG(align::ID id, PclHLS HLS) {
0500   const auto& tns = pedeLabeler_->alignableTracker()->trackerNameSpace();
0501 
0502   switch (HLS) {
0503     case PclHLS::TPBLadderLayer1:
0504       return (tns.tpb().halfBarrelNumber(id) == 1) ? tns.tpb().ladderNumber(id) + indexHelper[HLS].first
0505                                                    : tns.tpb().ladderNumber(id) + indexHelper[HLS].second;
0506     case PclHLS::TPBLadderLayer2:
0507       return (tns.tpb().halfBarrelNumber(id) == 1) ? tns.tpb().ladderNumber(id) + indexHelper[HLS].first
0508                                                    : tns.tpb().ladderNumber(id) + indexHelper[HLS].second;
0509     case PclHLS::TPBLadderLayer3:
0510       return (tns.tpb().halfBarrelNumber(id) == 1) ? tns.tpb().ladderNumber(id) + indexHelper[HLS].first
0511                                                    : tns.tpb().ladderNumber(id) + indexHelper[HLS].second;
0512     case PclHLS::TPBLadderLayer4:
0513       return (tns.tpb().halfBarrelNumber(id) == 1) ? tns.tpb().ladderNumber(id) + indexHelper[HLS].first
0514                                                    : tns.tpb().ladderNumber(id) + indexHelper[HLS].second;
0515     case PclHLS::TPEPanelDisk1:
0516       return (tns.tpe().halfCylinderNumber(id) == 1)
0517                  ? (tns.tpe().bladeNumber(id) * 2 - (tns.tpe().panelNumber(id) % 2)) + indexHelper[HLS].first
0518                  : (tns.tpe().bladeNumber(id) * 2 - (tns.tpe().panelNumber(id) % 2)) + indexHelper[HLS].second;
0519     case PclHLS::TPEPanelDisk2:
0520       return (tns.tpe().halfCylinderNumber(id) == 1)
0521                  ? (tns.tpe().bladeNumber(id) * 2 - (tns.tpe().panelNumber(id) % 2)) + indexHelper[HLS].first
0522                  : (tns.tpe().bladeNumber(id) * 2 - (tns.tpe().panelNumber(id) % 2)) + indexHelper[HLS].second;
0523     case PclHLS::TPEPanelDisk3:
0524       return (tns.tpe().halfCylinderNumber(id) == 1)
0525                  ? (tns.tpe().bladeNumber(id) * 2 - (tns.tpe().panelNumber(id) % 2)) + indexHelper[HLS].first
0526                  : (tns.tpe().bladeNumber(id) * 2 - (tns.tpe().panelNumber(id) % 2)) + indexHelper[HLS].second;
0527     case PclHLS::TPEPanelDiskM1:
0528       return (tns.tpe().halfCylinderNumber(id) == 1)
0529                  ? (tns.tpe().bladeNumber(id) * 2 - (tns.tpe().panelNumber(id) % 2)) + indexHelper[HLS].first
0530                  : (tns.tpe().bladeNumber(id) * 2 - (tns.tpe().panelNumber(id) % 2)) + indexHelper[HLS].second;
0531     case PclHLS::TPEPanelDiskM2:
0532       return (tns.tpe().halfCylinderNumber(id) == 1)
0533                  ? (tns.tpe().bladeNumber(id) * 2 - (tns.tpe().panelNumber(id) % 2)) + indexHelper[HLS].first
0534                  : (tns.tpe().bladeNumber(id) * 2 - (tns.tpe().panelNumber(id) % 2)) + indexHelper[HLS].second;
0535     case PclHLS::TPEPanelDiskM3:
0536       return (tns.tpe().halfCylinderNumber(id) == 1)
0537                  ? (tns.tpe().bladeNumber(id) * 2 - (tns.tpe().panelNumber(id) % 2)) + indexHelper[HLS].first
0538                  : (tns.tpe().bladeNumber(id) * 2 - (tns.tpe().panelNumber(id) % 2)) + indexHelper[HLS].second;
0539     default:
0540       return -200;
0541   }
0542 }
0543 
0544 //=============================================================================
0545 //===   STATIC CONST MEMBER DEFINITION                                      ===
0546 //=============================================================================
0547 constexpr std::array<double, 6> MillePedeFileReader::multiplier_;