Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-03-26 01:51:13

0001 
0002 #include "FWCore/ParameterSet/interface/ParameterDescription.h"
0003 
0004 #include "DataFormats/Provenance/interface/EventID.h"
0005 #include "DataFormats/Provenance/interface/EventRange.h"
0006 #include "DataFormats/Provenance/interface/LuminosityBlockID.h"
0007 #include "DataFormats/Provenance/interface/LuminosityBlockRange.h"
0008 #include "FWCore/ParameterSet/interface/DocFormatHelper.h"
0009 #include "FWCore/Utilities/interface/FileInPath.h"
0010 #include "FWCore/ParameterSet/src/FillDescriptionFromPSet.h"
0011 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0012 #include "FWCore/ParameterSet/interface/VParameterSetEntry.h"
0013 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0014 #include "FWCore/Utilities/interface/Algorithms.h"
0015 #include "FWCore/Utilities/interface/EDMException.h"
0016 #include "FWCore/Utilities/interface/InputTag.h"
0017 #include "FWCore/Utilities/interface/ESInputTag.h"
0018 
0019 #include <cassert>
0020 #include <cstdlib>
0021 #include <iomanip>
0022 #include <ostream>
0023 #include <sstream>
0024 
0025 namespace edm {
0026 
0027   // =================================================================
0028 
0029   ParameterDescription<ParameterSetDescription>::ParameterDescription(std::string const& iLabel,
0030                                                                       ParameterSetDescription const& value,
0031                                                                       bool isTracked,
0032                                                                       Comment const& iComment)
0033       : ParameterDescriptionBase(iLabel, k_PSet, isTracked, true, iComment),
0034         psetDesc_(new ParameterSetDescription(value)) {}
0035 
0036   ParameterDescription<ParameterSetDescription>::ParameterDescription(char const* iLabel,
0037                                                                       ParameterSetDescription const& value,
0038                                                                       bool isTracked,
0039                                                                       Comment const& iComment)
0040       : ParameterDescriptionBase(iLabel, k_PSet, isTracked, true, iComment),
0041         psetDesc_(new ParameterSetDescription(value)) {}
0042 
0043   ParameterDescription<ParameterSetDescription>::~ParameterDescription() {}
0044 
0045   void ParameterDescription<ParameterSetDescription>::validate_(ParameterSet& pset,
0046                                                                 std::set<std::string>& validatedLabels,
0047                                                                 Modifier modifier) const {
0048     bool exists = pset.existsAs<ParameterSet>(label(), isTracked());
0049 
0050     if (exists) {
0051       validatedLabels.insert(label());
0052     } else if (pset.existsAs<ParameterSet>(label(), !isTracked())) {
0053       throwParameterWrongTrackiness();
0054     } else if (pset.exists(label())) {
0055       throwParameterWrongType();
0056     }
0057 
0058     if (modifier == Modifier::kNone && !exists) {
0059       if (isTracked()) {
0060         pset.addParameter(label(), ParameterSet());
0061       } else {
0062         pset.addUntrackedParameter(label(), ParameterSet());
0063       }
0064       validatedLabels.insert(label());
0065     }
0066 
0067     exists = pset.existsAs<ParameterSet>(label(), isTracked());
0068 
0069     if (exists) {
0070       if (modifier == Modifier::kObsolete) {
0071         edm::LogWarning("Configuration") << "ignoring obsolete parameter '" << label() << "'";
0072         return;
0073       }
0074       if (pset.isRegistered()) {
0075         pset.invalidateRegistration("");
0076       }
0077       ParameterSet* containedPSet = pset.getPSetForUpdate(label());
0078       psetDesc_->validate(*containedPSet);
0079     }
0080   }
0081 
0082   void ParameterDescription<ParameterSetDescription>::printDefault_(std::ostream& os,
0083                                                                     bool writeToCfi,
0084                                                                     DocFormatHelper& dfh) const {
0085     os << "see Section " << dfh.section() << "." << dfh.counter();
0086     if (!writeToCfi)
0087       os << " (do not write to cfi)";
0088     os << "\n";
0089   }
0090 
0091   bool ParameterDescription<ParameterSetDescription>::hasNestedContent_() const { return true; }
0092 
0093   void ParameterDescription<ParameterSetDescription>::printNestedContent_(std::ostream& os,
0094                                                                           bool /*optional*/,
0095                                                                           DocFormatHelper& dfh) const {
0096     int indentation = dfh.indentation();
0097     if (dfh.parent() != DocFormatHelper::TOP) {
0098       indentation -= DocFormatHelper::offsetSectionContent();
0099     }
0100 
0101     std::stringstream ss;
0102     ss << dfh.section() << "." << dfh.counter();
0103     std::string newSection = ss.str();
0104 
0105     printSpaces(os, indentation);
0106     os << "Section " << newSection << " " << label() << " PSet description:\n";
0107     if (!dfh.brief())
0108       os << "\n";
0109 
0110     DocFormatHelper new_dfh(dfh);
0111     new_dfh.init();
0112     new_dfh.setSection(newSection);
0113     if (dfh.parent() == DocFormatHelper::TOP) {
0114       new_dfh.setIndentation(indentation + DocFormatHelper::offsetSectionContent());
0115     }
0116     psetDesc_->print(os, new_dfh);
0117   }
0118 
0119   bool ParameterDescription<ParameterSetDescription>::exists_(ParameterSet const& pset) const {
0120     return pset.existsAs<ParameterSet>(label(), isTracked());
0121   }
0122 
0123   ParameterSetDescription const* ParameterDescription<ParameterSetDescription>::parameterSetDescription() const {
0124     return psetDesc_.operator->();
0125   }
0126 
0127   ParameterSetDescription* ParameterDescription<ParameterSetDescription>::parameterSetDescription() {
0128     return psetDesc_.operator->();
0129   }
0130 
0131   void ParameterDescription<ParameterSetDescription>::writeCfi_(std::ostream& os,
0132                                                                 int indentation,
0133                                                                 CfiOptions& options) const {
0134     bool startWithComma = false;
0135     indentation += 2;
0136     psetDesc_->writeCfi(os, startWithComma, indentation, options);
0137   }
0138 
0139   void ParameterDescription<ParameterSetDescription>::writeDoc_(std::ostream&, int /*indentation*/) const {}
0140 
0141   // These next two should not be needed for this specialization
0142   bool ParameterDescription<ParameterSetDescription>::exists_(ParameterSet const&, bool /*isTracked*/) const {
0143     throw Exception(errors::LogicError);
0144     return true;
0145   }
0146 
0147   void ParameterDescription<ParameterSetDescription>::insertDefault_(ParameterSet&) const {
0148     throw Exception(errors::LogicError);
0149     return;
0150   }
0151 
0152   // =================================================================
0153 
0154   ParameterDescription<std::vector<ParameterSet> >::ParameterDescription(std::string const& iLabel,
0155                                                                          ParameterSetDescription const& psetDesc,
0156                                                                          bool isTracked,
0157                                                                          std::vector<ParameterSet> const& vPset,
0158                                                                          Comment const& iComment)
0159       : ParameterDescriptionBase(iLabel, k_VPSet, isTracked, true, iComment),
0160         psetDesc_(new ParameterSetDescription(psetDesc)),
0161         vPset_(vPset),
0162         partOfDefaultOfVPSet_(false) {}
0163 
0164   ParameterDescription<std::vector<ParameterSet> >::ParameterDescription(char const* iLabel,
0165                                                                          ParameterSetDescription const& psetDesc,
0166                                                                          bool isTracked,
0167                                                                          std::vector<ParameterSet> const& vPset,
0168                                                                          Comment const& iComment)
0169       : ParameterDescriptionBase(iLabel, k_VPSet, isTracked, true, iComment),
0170         psetDesc_(new ParameterSetDescription(psetDesc)),
0171         vPset_(vPset),
0172         partOfDefaultOfVPSet_(false) {}
0173 
0174   ParameterDescription<std::vector<ParameterSet> >::ParameterDescription(std::string const& iLabel,
0175                                                                          ParameterSetDescription const& psetDesc,
0176                                                                          bool isTracked,
0177                                                                          Comment const& iComment)
0178       : ParameterDescriptionBase(iLabel, k_VPSet, isTracked, false, iComment),
0179         psetDesc_(new ParameterSetDescription(psetDesc)),
0180         vPset_(),
0181         partOfDefaultOfVPSet_(false) {}
0182 
0183   ParameterDescription<std::vector<ParameterSet> >::ParameterDescription(char const* iLabel,
0184                                                                          ParameterSetDescription const& psetDesc,
0185                                                                          bool isTracked,
0186                                                                          Comment const& iComment)
0187       : ParameterDescriptionBase(iLabel, k_VPSet, isTracked, false, iComment),
0188         psetDesc_(new ParameterSetDescription(psetDesc)),
0189         vPset_(),
0190         partOfDefaultOfVPSet_(false) {}
0191 
0192   ParameterDescription<std::vector<ParameterSet> >::~ParameterDescription() {}
0193 
0194   ParameterSetDescription const* ParameterDescription<std::vector<ParameterSet> >::parameterSetDescription() const {
0195     return psetDesc_.operator->();
0196   }
0197 
0198   ParameterSetDescription* ParameterDescription<std::vector<ParameterSet> >::parameterSetDescription() {
0199     return psetDesc_.operator->();
0200   }
0201 
0202   void ParameterDescription<std::vector<ParameterSet> >::validate_(ParameterSet& pset,
0203                                                                    std::set<std::string>& validatedLabels,
0204                                                                    Modifier modifier) const {
0205     bool exists = pset.existsAs<std::vector<ParameterSet> >(label(), isTracked());
0206 
0207     if (exists) {
0208       validatedLabels.insert(label());
0209     } else if (pset.existsAs<std::vector<ParameterSet> >(label(), !isTracked())) {
0210       throwParameterWrongTrackiness();
0211     } else if (pset.exists(label())) {
0212       throwParameterWrongType();
0213     }
0214 
0215     if (!exists && modifier == Modifier::kNone) {
0216       if (hasDefault()) {
0217         if (isTracked()) {
0218           pset.addParameter(label(), vPset_);
0219         } else {
0220           pset.addUntrackedParameter(label(), vPset_);
0221         }
0222         validatedLabels.insert(label());
0223       } else {
0224         throwMissingRequiredNoDefault();
0225       }
0226     }
0227 
0228     exists = pset.existsAs<std::vector<ParameterSet> >(label(), isTracked());
0229     if (exists) {
0230       if (modifier == Modifier::kObsolete) {
0231         edm::LogWarning("Configuration") << "ignoring obsolete parameter '" << label() << "'";
0232         return;
0233       }
0234       VParameterSetEntry* vpsetEntry = pset.getPSetVectorForUpdate(label());
0235       assert(vpsetEntry);
0236 
0237       for (unsigned i = 0; i < vpsetEntry->size(); ++i) {
0238         psetDesc_->validate(vpsetEntry->psetInVector(i));
0239       }
0240     }
0241   }
0242 
0243   void ParameterDescription<std::vector<ParameterSet> >::printDefault_(std::ostream& os,
0244                                                                        bool writeToCfi,
0245                                                                        DocFormatHelper& dfh) const {
0246     os << "see Section " << dfh.section() << "." << dfh.counter();
0247     if (!writeToCfi)
0248       os << " (do not write to cfi)";
0249     os << "\n";
0250   }
0251 
0252   bool ParameterDescription<std::vector<ParameterSet> >::hasNestedContent_() const { return true; }
0253 
0254   void ParameterDescription<std::vector<ParameterSet> >::printNestedContent_(std::ostream& os,
0255                                                                              bool /*optional*/,
0256                                                                              DocFormatHelper& dfh) const {
0257     int indentation = dfh.indentation();
0258     if (dfh.parent() != DocFormatHelper::TOP) {
0259       indentation -= DocFormatHelper::offsetSectionContent();
0260     }
0261 
0262     if (!partOfDefaultOfVPSet_) {
0263       printSpaces(os, indentation);
0264       os << "Section " << dfh.section() << "." << dfh.counter() << " " << label() << " VPSet description:\n";
0265 
0266       printSpaces(os, indentation + DocFormatHelper::offsetSectionContent());
0267       os << "All elements will be validated using the PSet description in Section " << dfh.section() << "."
0268          << dfh.counter() << ".1.\n";
0269     } else {
0270       printSpaces(os, indentation);
0271       os << "Section " << dfh.section() << "." << dfh.counter() << " "
0272          << " VPSet description for VPSet that is part of the default of a containing VPSet:\n";
0273     }
0274 
0275     printSpaces(os, indentation + DocFormatHelper::offsetSectionContent());
0276 
0277     unsigned subsectionOffset = 2;
0278     if (partOfDefaultOfVPSet_)
0279       subsectionOffset = 1;
0280 
0281     if (hasDefault()) {
0282       if (vPset_.empty())
0283         os << "The default VPSet is empty.\n";
0284       else if (vPset_.size() == 1U)
0285         os << "The default VPSet has 1 element.\n";
0286       else
0287         os << "The default VPSet has " << vPset_.size() << " elements.\n";
0288 
0289       if (!vPset_.empty()) {
0290         for (unsigned i = 0; i < vPset_.size(); ++i) {
0291           printSpaces(os, indentation + DocFormatHelper::offsetSectionContent());
0292           os << "[" << (i) << "]: see Section " << dfh.section() << "." << dfh.counter() << "."
0293              << (i + subsectionOffset) << "\n";
0294         }
0295       }
0296     } else {
0297       os << "Does not have a default VPSet.\n";
0298     }
0299 
0300     if (!dfh.brief())
0301       os << "\n";
0302 
0303     if (!partOfDefaultOfVPSet_) {
0304       std::stringstream ss;
0305       ss << dfh.section() << "." << dfh.counter() << ".1";
0306       std::string newSection = ss.str();
0307 
0308       printSpaces(os, indentation);
0309       os << "Section " << newSection << " description of PSet used to validate elements of VPSet:\n";
0310       if (!dfh.brief())
0311         os << "\n";
0312 
0313       DocFormatHelper new_dfh(dfh);
0314       new_dfh.init();
0315       new_dfh.setSection(newSection);
0316       if (dfh.parent() == DocFormatHelper::TOP) {
0317         new_dfh.setIndentation(indentation + DocFormatHelper::offsetSectionContent());
0318       }
0319       psetDesc_->print(os, new_dfh);
0320     }
0321 
0322     if (hasDefault()) {
0323       for (unsigned i = 0; i < vPset_.size(); ++i) {
0324         std::stringstream ss;
0325         ss << dfh.section() << "." << dfh.counter() << "." << (i + subsectionOffset);
0326         std::string newSection = ss.str();
0327 
0328         printSpaces(os, indentation);
0329         os << "Section " << newSection << " PSet description of "
0330            << "default VPSet element [" << i << "]\n";
0331         if (!dfh.brief())
0332           os << "\n";
0333 
0334         DocFormatHelper new_dfh(dfh);
0335         new_dfh.init();
0336         new_dfh.setSection(newSection);
0337         if (dfh.parent() == DocFormatHelper::TOP) {
0338           new_dfh.setIndentation(indentation + DocFormatHelper::offsetSectionContent());
0339         }
0340 
0341         ParameterSetDescription defaultDescription;
0342         fillDescriptionFromPSet(vPset_[i], defaultDescription);
0343         defaultDescription.print(os, new_dfh);
0344       }
0345     }
0346   }
0347 
0348   bool ParameterDescription<std::vector<ParameterSet> >::exists_(ParameterSet const& pset) const {
0349     return pset.existsAs<std::vector<ParameterSet> >(label(), isTracked());
0350   }
0351 
0352   void ParameterDescription<std::vector<ParameterSet> >::writeOneElementToCfi(
0353       ParameterSet const& pset, std::ostream& os, int indentation, CfiOptions& options, bool& nextOneStartsWithAComma) {
0354     if (nextOneStartsWithAComma)
0355       os << ",";
0356     nextOneStartsWithAComma = true;
0357     os << "\n";
0358     printSpaces(os, indentation + 2);
0359 
0360     os << "cms.PSet(";
0361 
0362     bool startWithComma = false;
0363     int indent = indentation + 4;
0364 
0365     ParameterSetDescription psetDesc;
0366     fillDescriptionFromPSet(pset, psetDesc);
0367     CfiOptions ops = cfi::Typed{};
0368     psetDesc.writeCfi(os, startWithComma, indent, ops);
0369 
0370     os << ")";
0371   }
0372 
0373   void ParameterDescription<std::vector<ParameterSet> >::writeCfi_(std::ostream& os,
0374                                                                    int indentation,
0375                                                                    CfiOptions& options) const {
0376     bool nextOneStartsWithAComma = false;
0377     for (auto const& p : vPset_) {
0378       writeOneElementToCfi(p, os, indentation, options, nextOneStartsWithAComma);
0379     }
0380     if (cfi::shouldWriteUntyped(options) or psetDesc_->empty() or psetDesc_->anythingAllowed() or
0381         psetDesc_->isUnknown()) {
0382       os << "\n";
0383     } else {
0384       if (not vPset_.empty()) {
0385         os << ",";
0386       }
0387       os << "\n";
0388       printSpaces(os, indentation + 2);
0389       CfiOptions fullOp = cfi::Typed{};
0390       os << "template = cms.PSetTemplate(";
0391       psetDesc_->writeCfi(os, false, indentation + 4, fullOp);
0392       os << ")\n";
0393     }
0394     printSpaces(os, indentation);
0395   }
0396 
0397   void ParameterDescription<std::vector<ParameterSet> >::writeDoc_(std::ostream&, int /*indentation*/) const {}
0398 
0399   // These next two should not be needed for this specialization
0400   bool ParameterDescription<std::vector<ParameterSet> >::exists_(ParameterSet const&, bool /*isTracked*/) const {
0401     throw Exception(errors::LogicError);
0402     return true;
0403   }
0404 
0405   void ParameterDescription<std::vector<ParameterSet> >::insertDefault_(ParameterSet&) const {
0406     throw Exception(errors::LogicError);
0407     return;
0408   }
0409 
0410   // =================================================================
0411 
0412   namespace writeParameterValue {
0413 
0414     template <typename T>
0415     void writeSingleValue(std::ostream& os, T const& value, ValueFormat) {
0416       os << value;
0417     }
0418 
0419     // Specialize this for cases where the operator<< does not give
0420     // the proper formatting for a configuration file.
0421 
0422     // Formatting the doubles is a little tricky.  It is a requirement
0423     // that when a value of ***type double*** is added to a ParameterSetDescription
0424     // the EXACT same value of type double will be created and passed to the
0425     // ParameterSet after the cfi files have been read.  The tricky part
0426     // is these values usually appear in the C++ code and cfi file as text
0427     // strings (in decimal form).  We do our best to force the text
0428     // string in the C++ code to be the same as the text string in the
0429     // cfi file by judiciously rounding to smaller precision when possible.
0430     // But it is not always possible to force the text strings to be the
0431     // same.  Generally, there are differences when the text string in the
0432     // C++ code has many digits (probably more than a human will ever type).
0433     // Even in cases where the text strings differ, the values stored in
0434     // memory in variables of type double will be exactly the same.
0435     // The alternative to the approach here is to store the values as strings,
0436     // but that approach was rejected because it would require the
0437     // ParameterSetDescription to know how to parse the strings.
0438     void formatDouble(double value, std::string& result) {
0439       {
0440         std::stringstream ss;
0441         ss << std::setprecision(17) << value;
0442         result = ss.str();
0443       }
0444       if (result.size() > 15 && std::string::npos != result.find('.')) {
0445         std::stringstream ss;
0446         ss << std::setprecision(15) << value;
0447         std::string resultLessPrecision = ss.str();
0448 
0449         if (resultLessPrecision.size() < result.size() - 2) {
0450           double test = std::strtod(resultLessPrecision.c_str(), nullptr);
0451           if (test == value) {
0452             result = resultLessPrecision;
0453           }
0454         }
0455       }
0456     }
0457 
0458     template <>
0459     void writeSingleValue<double>(std::ostream& os, double const& value, ValueFormat) {
0460       std::string sValue;
0461       formatDouble(value, sValue);
0462       os << sValue;
0463     }
0464 
0465     template <>
0466     void writeSingleValue<bool>(std::ostream& os, bool const& value, ValueFormat) {
0467       value ? os << "True" : os << "False";
0468     }
0469 
0470     template <>
0471     void writeSingleValue<std::string>(std::ostream& os, std::string const& value, ValueFormat) {
0472       os << "'" << value << "'";
0473     }
0474 
0475     template <>
0476     void writeSingleValue<EventID>(std::ostream& os, EventID const& value, ValueFormat format) {
0477       if (format == CFI) {
0478         os << value.run() << ", " << value.luminosityBlock() << ", " << value.event();
0479       } else {
0480         if (value.luminosityBlock() == 0U) {
0481           os << value.run() << ":" << value.event();
0482         } else {
0483           os << value.run() << ":" << value.luminosityBlock() << ":" << value.event();
0484         }
0485       }
0486     }
0487 
0488     template <>
0489     void writeSingleValue<LuminosityBlockID>(std::ostream& os, LuminosityBlockID const& value, ValueFormat format) {
0490       if (format == CFI)
0491         os << value.run() << ", " << value.luminosityBlock();
0492       else
0493         os << value.run() << ":" << value.luminosityBlock();
0494     }
0495 
0496     template <>
0497     void writeSingleValue<EventRange>(std::ostream& os, EventRange const& value, ValueFormat format) {
0498       if (value.startLumi() == 0U) {
0499         if (format == CFI)
0500           os << "'" << value.startRun() << ":" << value.startEvent() << "-" << value.endRun() << ":" << value.endEvent()
0501              << "'";
0502         else
0503           os << value.startRun() << ":" << value.startEvent() << "-" << value.endRun() << ":" << value.endEvent();
0504       } else {
0505         if (format == CFI)
0506           os << "'" << value.startRun() << ":" << value.startLumi() << ":" << value.startEvent() << "-"
0507              << value.endRun() << ":" << value.endLumi() << ":" << value.endEvent() << "'";
0508         else
0509           os << value.startRun() << ":" << value.startLumi() << ":" << value.startEvent() << "-" << value.endRun()
0510              << ":" << value.endLumi() << ":" << value.endEvent();
0511       }
0512     }
0513 
0514     template <>
0515     void writeSingleValue<LuminosityBlockRange>(std::ostream& os,
0516                                                 LuminosityBlockRange const& value,
0517                                                 ValueFormat format) {
0518       if (format == CFI)
0519         os << "'" << value.startRun() << ":" << value.startLumi() << "-" << value.endRun() << ":" << value.endLumi()
0520            << "'";
0521       else
0522         os << value.startRun() << ":" << value.startLumi() << "-" << value.endRun() << ":" << value.endLumi();
0523     }
0524 
0525     template <>
0526     void writeSingleValue<InputTag>(std::ostream& os, InputTag const& value, ValueFormat format) {
0527       if (format == CFI) {
0528         os << "'" << value.label() << "'";
0529         if (!value.instance().empty() || !value.process().empty()) {
0530           os << ", '" << value.instance() << "'";
0531         }
0532         if (!value.process().empty()) {
0533           os << ", '" << value.process() << "'";
0534         }
0535       } else {
0536         os << "'" << value.label();
0537         if (!value.instance().empty() || !value.process().empty()) {
0538           os << ":" << value.instance();
0539         }
0540         if (!value.process().empty()) {
0541           os << ":" << value.process();
0542         }
0543         os << "'";
0544       }
0545     }
0546 
0547     template <>
0548     void writeSingleValue<ESInputTag>(std::ostream& os, ESInputTag const& value, ValueFormat format) {
0549       if (format == CFI) {
0550         os << "'" << value.module() << "', '" << value.data() << "'";
0551       } else {
0552         os << "'" << value.module() << ":" << value.data() << "'";
0553       }
0554     }
0555 
0556     template <>
0557     void writeSingleValue<FileInPath>(std::ostream& os, FileInPath const& value, ValueFormat) {
0558       os << "'" << value.relativePath() << "'";
0559     }
0560 
0561     template <typename T>
0562     void writeValue(std::ostream& os, T const& value_, ValueFormat format) {
0563       std::ios_base::fmtflags ff = os.flags(std::ios_base::dec);
0564       os.width(0);
0565       writeSingleValue<T>(os, value_, format);
0566       os.flags(ff);
0567     }
0568 
0569     template <typename T>
0570     void writeValueInVector(std::ostream& os, T const& value, ValueFormat format) {
0571       writeSingleValue<T>(os, value, format);
0572     }
0573 
0574     // Specializations for cases where we write the single values into
0575     // vectors differently than when there is only one not in a vector.
0576     template <>
0577     void writeValueInVector<EventID>(std::ostream& os, EventID const& value, ValueFormat format) {
0578       if (value.luminosityBlock() == 0U) {
0579         if (format == CFI)
0580           os << "'" << value.run() << ":" << value.event() << "'";
0581         else
0582           os << value.run() << ":" << value.event();
0583       } else {
0584         if (format == CFI)
0585           os << "'" << value.run() << ":" << value.luminosityBlock() << ":" << value.event() << "'";
0586         else
0587           os << value.run() << ":" << value.luminosityBlock() << ":" << value.event();
0588       }
0589     }
0590 
0591     template <>
0592     void writeValueInVector<LuminosityBlockID>(std::ostream& os, LuminosityBlockID const& value, ValueFormat format) {
0593       if (format == CFI)
0594         os << "'" << value.run() << ":" << value.luminosityBlock() << "'";
0595       else
0596         os << value.run() << ":" << value.luminosityBlock();
0597     }
0598 
0599     template <>
0600     void writeValueInVector<InputTag>(std::ostream& os, InputTag const& value, ValueFormat) {
0601       os << "'" << value.label();
0602       if (!value.instance().empty() || !value.process().empty()) {
0603         os << ":" << value.instance();
0604       }
0605       if (!value.process().empty()) {
0606         os << ":" << value.process();
0607       }
0608       os << "'";
0609     }
0610 
0611     template <>
0612     void writeValueInVector<ESInputTag>(std::ostream& os, ESInputTag const& value, ValueFormat) {
0613       os << "'" << value.module() << ":" << value.data() << "'";
0614     }
0615 
0616     template <typename T>
0617     void writeValueInVectorWithSpace(
0618         T const& value, std::ostream& os, int indentation, bool& startWithComma, ValueFormat format, int& i) {
0619       if (startWithComma && format == CFI)
0620         os << ",";
0621       startWithComma = true;
0622       os << "\n" << std::setw(indentation) << "";
0623       if (format == DOC)
0624         os << "[" << i << "]: ";
0625       writeValueInVector<T>(os, value, format);
0626       ++i;
0627     }
0628 
0629     template <typename T>
0630     void writeVector(std::ostream& os, int indentation, std::vector<T> const& value_, ValueFormat format) {
0631       std::ios_base::fmtflags ff = os.flags(std::ios_base::dec);
0632       char oldFill = os.fill();
0633       os.width(0);
0634       if (value_.empty() && format == DOC) {
0635         os << "empty";
0636       } else if (value_.size() == 1U && format == CFI) {
0637         writeValueInVector<T>(os, value_[0], format);
0638       } else if (!value_.empty()) {
0639         if (format == DOC)
0640           os << "(vector size = " << value_.size() << ")";
0641         if (format == CFI and value_.size() > 255U)
0642           os << " *(";
0643         os.fill(' ');
0644         bool startWithComma = false;
0645         int i = 0;
0646         for_all(value_,
0647                 std::bind(&writeValueInVectorWithSpace<T>,
0648                           std::placeholders::_1,
0649                           std::ref(os),
0650                           indentation + 2,
0651                           std::ref(startWithComma),
0652                           format,
0653                           std::ref(i)));
0654         if (format == CFI)
0655           os << "\n" << std::setw(indentation) << "";
0656         if (format == CFI and value_.size() > 255U)
0657           os << ") ";
0658       }
0659       os.flags(ff);
0660       os.fill(oldFill);
0661     }
0662 
0663     void writeValue(std::ostream& os, int, int const& value_, ValueFormat format) {
0664       writeValue<int>(os, value_, format);
0665     }
0666 
0667     void writeValue(std::ostream& os, int indentation, std::vector<int> const& value_, ValueFormat format) {
0668       writeVector<int>(os, indentation, value_, format);
0669     }
0670 
0671     void writeValue(std::ostream& os, int, unsigned const& value_, ValueFormat format) {
0672       writeValue<unsigned>(os, value_, format);
0673     }
0674 
0675     void writeValue(std::ostream& os, int indentation, std::vector<unsigned> const& value_, ValueFormat format) {
0676       writeVector<unsigned>(os, indentation, value_, format);
0677     }
0678 
0679     void writeValue(std::ostream& os, int, long long const& value_, ValueFormat format) {
0680       writeValue<long long>(os, value_, format);
0681     }
0682 
0683     void writeValue(std::ostream& os, int indentation, std::vector<long long> const& value_, ValueFormat format) {
0684       writeVector<long long>(os, indentation, value_, format);
0685     }
0686 
0687     void writeValue(std::ostream& os, int, unsigned long long const& value_, ValueFormat format) {
0688       writeValue<unsigned long long>(os, value_, format);
0689     }
0690 
0691     void writeValue(std::ostream& os,
0692                     int indentation,
0693                     std::vector<unsigned long long> const& value_,
0694                     ValueFormat format) {
0695       writeVector<unsigned long long>(os, indentation, value_, format);
0696     }
0697 
0698     void writeValue(std::ostream& os, int, double const& value_, ValueFormat format) {
0699       writeValue<double>(os, value_, format);
0700     }
0701 
0702     void writeValue(std::ostream& os, int indentation, std::vector<double> const& value_, ValueFormat format) {
0703       writeVector<double>(os, indentation, value_, format);
0704     }
0705 
0706     void writeValue(std::ostream& os, int, bool const& value_, ValueFormat format) {
0707       writeValue<bool>(os, value_, format);
0708     }
0709 
0710     void writeValue(std::ostream& os, int, std::string const& value_, ValueFormat format) {
0711       writeValue<std::string>(os, value_, format);
0712     }
0713 
0714     void writeValue(std::ostream& os, int indentation, std::vector<std::string> const& value_, ValueFormat format) {
0715       writeVector<std::string>(os, indentation, value_, format);
0716     }
0717 
0718     void writeValue(std::ostream& os, int, EventID const& value_, ValueFormat format) {
0719       writeValue<EventID>(os, value_, format);
0720     }
0721 
0722     void writeValue(std::ostream& os, int indentation, std::vector<EventID> const& value_, ValueFormat format) {
0723       writeVector<EventID>(os, indentation, value_, format);
0724     }
0725 
0726     void writeValue(std::ostream& os, int, LuminosityBlockID const& value_, ValueFormat format) {
0727       writeValue<LuminosityBlockID>(os, value_, format);
0728     }
0729 
0730     void writeValue(std::ostream& os,
0731                     int indentation,
0732                     std::vector<LuminosityBlockID> const& value_,
0733                     ValueFormat format) {
0734       writeVector<LuminosityBlockID>(os, indentation, value_, format);
0735     }
0736 
0737     void writeValue(std::ostream& os, int, LuminosityBlockRange const& value_, ValueFormat format) {
0738       writeValue<LuminosityBlockRange>(os, value_, format);
0739     }
0740 
0741     void writeValue(std::ostream& os,
0742                     int indentation,
0743                     std::vector<LuminosityBlockRange> const& value_,
0744                     ValueFormat format) {
0745       writeVector<LuminosityBlockRange>(os, indentation, value_, format);
0746     }
0747 
0748     void writeValue(std::ostream& os, int, EventRange const& value_, ValueFormat format) {
0749       writeValue<EventRange>(os, value_, format);
0750     }
0751 
0752     void writeValue(std::ostream& os, int indentation, std::vector<EventRange> const& value_, ValueFormat format) {
0753       writeVector<EventRange>(os, indentation, value_, format);
0754     }
0755 
0756     void writeValue(std::ostream& os, int, InputTag const& value_, ValueFormat format) {
0757       writeValue<InputTag>(os, value_, format);
0758     }
0759 
0760     void writeValue(std::ostream& os, int indentation, std::vector<InputTag> const& value_, ValueFormat format) {
0761       writeVector<InputTag>(os, indentation, value_, format);
0762     }
0763 
0764     void writeValue(std::ostream& os, int, ESInputTag const& value_, ValueFormat format) {
0765       writeValue<ESInputTag>(os, value_, format);
0766     }
0767 
0768     void writeValue(std::ostream& os, int indentation, std::vector<ESInputTag> const& value_, ValueFormat format) {
0769       writeVector<ESInputTag>(os, indentation, value_, format);
0770     }
0771 
0772     void writeValue(std::ostream& os, int, FileInPath const& value_, ValueFormat format) {
0773       writeValue<FileInPath>(os, value_, format);
0774     }
0775 
0776     bool hasNestedContent(int const&) { return false; }
0777     bool hasNestedContent(std::vector<int> const& value) { return value.size() > 5U; }
0778     bool hasNestedContent(unsigned const&) { return false; }
0779     bool hasNestedContent(std::vector<unsigned> const& value) { return value.size() > 5U; }
0780     bool hasNestedContent(long long const&) { return false; }
0781     bool hasNestedContent(std::vector<long long> const& value) { return value.size() > 5U; }
0782     bool hasNestedContent(unsigned long long const&) { return false; }
0783     bool hasNestedContent(std::vector<unsigned long long> const& value) { return value.size() > 5U; }
0784     bool hasNestedContent(double const&) { return false; }
0785     bool hasNestedContent(std::vector<double> const& value) { return value.size() > 5U; }
0786     bool hasNestedContent(bool const&) { return false; }
0787     bool hasNestedContent(std::string const&) { return false; }
0788     bool hasNestedContent(std::vector<std::string> const& value) { return value.size() > 5U; }
0789     bool hasNestedContent(EventID const&) { return false; }
0790     bool hasNestedContent(std::vector<EventID> const& value) { return value.size() > 5U; }
0791     bool hasNestedContent(LuminosityBlockID const&) { return false; }
0792     bool hasNestedContent(std::vector<LuminosityBlockID> const& value) { return value.size() > 5U; }
0793     bool hasNestedContent(LuminosityBlockRange const&) { return false; }
0794     bool hasNestedContent(std::vector<LuminosityBlockRange> const& value) { return value.size() > 5U; }
0795     bool hasNestedContent(EventRange const&) { return false; }
0796     bool hasNestedContent(std::vector<EventRange> const& value) { return value.size() > 5U; }
0797     bool hasNestedContent(InputTag const&) { return false; }
0798     bool hasNestedContent(std::vector<InputTag> const& value) { return value.size() > 5U; }
0799     bool hasNestedContent(ESInputTag const&) { return false; }
0800     bool hasNestedContent(std::vector<ESInputTag> const& value) { return value.size() > 5U; }
0801     bool hasNestedContent(FileInPath const&) { return false; }
0802   }  // namespace writeParameterValue
0803 }  // namespace edm