Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-10-09 08:30:27

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 #include "ActsPlugins/Mille/MillePedeSteering.hpp"
0010 
0011 #include "Acts/Utilities/Logger.hpp"
0012 #include "Acts/Utilities/Result.hpp"
0013 #include "ActsPlugins/Mille/MillePedeError.hpp"
0014 
0015 #include <filesystem>
0016 #include <format>
0017 #include <fstream>
0018 #include <map>
0019 
0020 using namespace ActsPlugins;
0021 
0022 namespace {
0023 using Strategy = ActsPlugins::MillePedeSolutionStrategy;
0024 using EqualityConstraint = ActsPlugins::MillePedeEqualityConstraint;
0025 using Config = ActsPlugins::MillePedeSteeringConfig;
0026 
0027 void addInputBlock(std::ofstream& out, const Config& conf,
0028                    const Acts::Logger& logger) {
0029   if (conf.inputFiles.empty()) {
0030     ACTS_WARNING(
0031         "You are about to generate a steering file without any input! Suit "
0032         "yourself, but this will probably not align anything...");
0033   }
0034   out << "*** Input files *** " << std::endl;
0035   out << "Cfiles " << std::endl;
0036   for (const std::string& f : conf.inputFiles) {
0037     std::filesystem::path p = f;
0038     /// always write absolute paths, to avoid issues when
0039     /// we run pede in a sub-directory
0040     if (p.is_relative()) {
0041       p = std::filesystem::current_path() / p;
0042     }
0043     out << p.string() << std::endl;
0044   }
0045   out << std::endl;
0046 }
0047 
0048 void addSolutionMethod(std::ofstream& out, const Config& conf,
0049                        const Acts::Logger& logger) {
0050   using enum Strategy;
0051   static const std::map<Strategy, std::string> stratNames{
0052       {Inversion, "inversion"},
0053       {Diagonalization, "diagonalization"},
0054       {Decomposition, "decomposition"},
0055       {FullMinRes, "fullMINRES"},
0056       {SparseMinRes, "sparseMINRES"},
0057       {FullMinResQlp, "fullMINRES-QLP"},
0058       {SparseMinResQlp, "sparseMINRES-QLP"},
0059       {FullLapack, "fullLAPACK"},
0060       {UnpackedLapack, "unpackedLAPACK"},
0061       {SparsePardiso, "sparsePARDISO"},
0062   };
0063   auto found = stratNames.find(conf.strategy);
0064   if (found == stratNames.end()) {
0065     ACTS_ERROR(
0066         "Strategy specified in the steering not yet supported in "
0067         "addSolutionMethod - this is a bug, please report to the devs");
0068     return;
0069   }
0070   out << "*** Solution method *** " << std::endl;
0071   out << std::format("method {}  {}  {}", found->second, conf.minIterations,
0072                      conf.convergenceLimit)
0073       << std::endl
0074       << std::endl;
0075 }
0076 
0077 void addConstraint(std::ofstream& out, const EqualityConstraint& constraint,
0078                    const Acts::Logger& /*logger*/) {
0079   out << std::format("Constraint {:.6f}", constraint.constraint) << std::endl;
0080   for (const auto& [label, weight] : constraint.labelsAndWeights) {
0081     out << std::format("    {}     {:.6f}", label, weight) << std::endl;
0082   }
0083   out << std::endl;
0084 }
0085 
0086 void addConstraintsBlock(std::ofstream& out, const Config& conf,
0087                          const Acts::Logger& logger) {
0088   for (const EqualityConstraint& con : conf.constraints) {
0089     addConstraint(out, con, logger);
0090   }
0091   out << std::endl;
0092 }
0093 
0094 void addOthers(std::ofstream& out, const Config& conf,
0095                const Acts::Logger& /*logger*/) {
0096   out << "*** Other steering flags " << std::endl;
0097   out << std::format("entries {} {} {}", std::get<0>(conf.entriesCut),
0098                      std::get<1>(conf.entriesCut), std::get<2>(conf.entriesCut))
0099       << std::endl;
0100   out << std::format("outlierdownweighting {} ", conf.outlierDownweighting)
0101       << std::endl;
0102   out << std::format("dwfractioncut {} ", conf.downweightFractionCut)
0103       << std::endl;
0104   out << std::format("threads {} {} ", conf.nOMPthreads, conf.nIOthreads)
0105       << std::endl;
0106   out << std::format("matiter {} ", conf.matIter) << std::endl;
0107   out << std::format("printcounts {} ", conf.printCounts) << std::endl;
0108   out << std::format("chisqcut {} {} ", conf.chi2Cut.first, conf.chi2Cut.second)
0109       << std::endl;
0110   if (conf.monitorResiduals) {
0111     out << " monitorresiduals" << std::endl;
0112   }
0113   if (conf.monitorPulls) {
0114     out << " monitorpulls" << std::endl;
0115   }
0116   if (conf.skipEmptyCons) {
0117     out << " skipemptycons" << std::endl;
0118   }
0119   if (conf.countRecords) {
0120     out << " countrecords" << std::endl;
0121   }
0122   out << std::endl;
0123   out << "*** User-specified config flags " << std::endl;
0124   for (const std::string& extraLine : conf.extraLines) {
0125     out << extraLine << std::endl;
0126   }
0127   out << std::endl;
0128 }
0129 }  // namespace
0130 
0131 Acts::Result<std::filesystem::path> ActsPlugins::generateMillePedeSteeringFile(
0132     const std::filesystem::path& destination, const Config& config,
0133     const Acts::Logger& logger) {
0134   std::ofstream theSteer(destination);
0135   if (!theSteer.is_open()) {
0136     ACTS_ERROR("Unable to create the MP steering file " << destination);
0137     return Acts::Result<std::filesystem::path>::failure(
0138         MillePedeError::UnableToWriteSteering);
0139   }
0140 
0141   theSteer << "*** Auto-generated Millepede steering file from ACTS *** "
0142            << std::endl;
0143 
0144   if (!config.constraints.empty()) {
0145     std::filesystem::path consFile = destination;
0146     consFile.replace_extension("cons.txt");
0147     theSteer << "*** Constraints file " << std::endl;
0148     if (consFile.is_relative()) {
0149       consFile = std::filesystem::current_path() / consFile;
0150     }
0151     theSteer << consFile.string() << std::endl;
0152     std::cout << consFile.string() << std::endl;
0153     std::ofstream theCons(consFile);
0154     if (!theSteer.is_open()) {
0155       ACTS_ERROR("Unable to create the MP constraints file " << consFile);
0156       return Acts::Result<std::filesystem::path>::failure(
0157           MillePedeError::UnableToWriteSteering);
0158     }
0159     addConstraintsBlock(theCons, config, logger());
0160     theCons.close();
0161   }
0162 
0163   addInputBlock(theSteer, config, logger());
0164   addSolutionMethod(theSteer, config, logger());
0165   addOthers(theSteer, config, logger());
0166 
0167   theSteer.close();
0168   return destination;
0169 }