CMS 3D CMS Logo

PedeReader.cc
Go to the documentation of this file.
1 
11 #include "PedeReader.h"
12 #include "PedeSteerer.h"
13 
16 
19 
21 
23 
25 
27 
28 #include <set>
29 #include <string>
30 #include <sstream>
31 
32 const unsigned int PedeReader::myMaxNumValPerParam = 5;
33 
34 //__________________________________________________________________________________________________
36  const PedeSteerer &steerer,
37  const PedeLabelerBase &labels,
38  const RunRange &runrange)
39  : mySteerer(steerer), myLabels(labels), myRunRange(runrange) {
40  std::string pedeResultFile(config.getUntrackedParameter<std::string>("fileDir"));
41  if (pedeResultFile.empty())
42  pedeResultFile = steerer.directory(); // includes final '/'
43  else if (pedeResultFile.find_last_of('/') != pedeResultFile.size() - 1) {
44  pedeResultFile += '/'; // directory may need '/'
45  }
46 
47  pedeResultFile += config.getParameter<std::string>("readFile");
48  myPedeResult.open(pedeResultFile.c_str(), std::ios::in);
49  if (!myPedeResult.is_open()) {
50  edm::LogError("Alignment") << "@SUB=PedeReader"
51  << "Problem opening pede output file " << pedeResultFile;
52  }
53 }
54 
55 //__________________________________________________________________________________________________
56 bool PedeReader::read(align::Alignables &alignables, bool setUserVars) {
57  alignables.clear();
58  myPedeResult.seekg(0, std::ios::beg); // back to start
59  bool isAllOk = true;
60 
61  std::set<Alignable *> uniqueList;
62 
63  edm::LogInfo("Alignment") << "@SUB=PedeReader::read"
64  << "will read parameters for run range " << myRunRange.first << " - " << myRunRange.second;
65 
66  // loop on lines of text file
67  unsigned int nParam = 0, nParamCalib = 0, nParamUnknown = 0;
68  while (myPedeResult.good() && !myPedeResult.eof()) {
69  // read label
70  unsigned int paramLabel = 0;
71  if (!this->readIfSameLine<unsigned int>(myPedeResult, paramLabel))
72  continue; // empty line?
73 
74  // read up to maximal number of pede result per parameter
75  float buffer[myMaxNumValPerParam] = {0.};
76  unsigned int bufferPos = 0;
77  for (; bufferPos < myMaxNumValPerParam; ++bufferPos) {
78  if (!this->readIfSameLine<float>(myPedeResult, buffer[bufferPos]))
79  break;
80  }
81 
82  // First check whether parameter is from any calibration (to be done before RunRange check:
83  // run dependence for them is not handled here, but probably inside the calibration).
84  // Double setting by calling read(..) twice for different RunRanges shouldn't harm.
85  std::pair<IntegratedCalibrationBase *, unsigned int> calibParam = myLabels.calibrationParamFromLabel(paramLabel);
86  if (calibParam.first) { // label belongs to a calibration
87  if (this->setCalibrationParameter(calibParam.first, calibParam.second, bufferPos, buffer)) {
88  ++nParamCalib;
89  } else {
90  edm::LogError("Alignment") << "@SUB=PedeReader::read"
91  << "Problems setting results of "
92  << "parameter " << calibParam.second << " to calibration '"
93  << calibParam.first->name() << "' (" << calibParam.first << ").";
94  isAllOk = false;
95  }
96  continue; // does not belong to any Alignable, so go to next line of file
97  }
98  // Now treat Alignables if paramLabel fits to run range, otherwise skip line:
99  const RunRange &runRange = myLabels.runRangeFromLabel(paramLabel);
100  if (!(runRange.first <= myRunRange.first && myRunRange.second <= runRange.second))
101  continue;
102 
103  Alignable *alignable = this->setParameter(paramLabel, bufferPos, buffer, setUserVars);
104  if (!alignable) {
105  // OK, e.g. for PedeReaderInputs: calibration parameters, but not yet known to labeler
106  ++nParamUnknown;
107  continue;
108  }
109  uniqueList.insert(alignable);
110  ++nParam;
111  }
112 
113  // add Alignables to output
114  alignables.insert(alignables.end(), uniqueList.begin(), uniqueList.end());
115 
116  std::stringstream out; // "@SUB=PedeReader::read" cannot yet go to 'out' for proper format
117  out << nParam << " parameters for " << alignables.size() << " alignables and " << nParamCalib << " for calibrations, "
118  << nParamUnknown << " parameters are unknown.\n";
119  if (nParamUnknown) {
120  edm::LogWarning("Alignment") << "@SUB=PedeReader::read" << out.str();
121  } else {
122  edm::LogInfo("Alignment") << "@SUB=PedeReader::read" << out.str();
123  }
124 
125  return isAllOk && (nParam + nParamCalib); // nParam+nParamCalib == 0: empty or bad file
126 }
127 
128 //__________________________________________________________________________________________________
129 template <class T>
130 bool PedeReader::readIfSameLine(std::ifstream &aStream, T &outValue) const {
131  while (true) {
132  const int aChar = aStream.get();
133  if (!aStream.good())
134  return false;
135 
136  switch (aChar) {
137  case ' ':
138  case '\t':
139  continue; // to next character
140  case '\n':
141  return false; // end of line
142  default:
143  aStream.unget();
144  aStream >> outValue;
145  if (aStream.fail()) { // not correct type 'T' (!aStream.good() is true also in case of EOF)
146  aStream.clear();
147  while (aStream.good() && aStream.get() != '\n')
148  ; // forward to end of line
149  return false;
150  } else {
151  return true;
152  }
153  } // switch
154  } // while
155 
156  edm::LogError("Alignment") << "@SUB=PedeReader::readIfSameLine"
157  << "Should never come here!";
158  return false;
159 }
160 
161 //__________________________________________________________________________________________________
163  unsigned int bufLength,
164  const float *buf,
165  bool setUserVars) const {
166  Alignable *alignable = myLabels.alignableFromLabel(paramLabel);
167  const unsigned int paramNum = myLabels.paramNumFromLabel(paramLabel);
168  const double cmsToPede = mySteerer.cmsToPedeFactor(paramNum);
169  if (alignable) {
170  AlignmentParameters *params = this->checkAliParams(alignable, setUserVars);
171  MillePedeVariables *userParams = // static cast ensured by previous checkAliParams
172  (setUserVars ? static_cast<MillePedeVariables *>(params->userVariables()) : nullptr);
173  // if (userParams && userParams->label() != myLabels.alignableLabelFromLabel(paramLabel)) {
174  if (userParams && userParams->label() != myLabels.alignableLabel(alignable)) {
175  edm::LogError("Alignment") << "@SUB=PedeReader::setParameter"
176  << "Label mismatch: paramLabel " << paramLabel << " for alignableLabel "
177  << userParams->label();
178  }
179 
180  AlgebraicVector parVec(params->parameters());
181  AlgebraicSymMatrix covMat(params->covariance());
182 
183  if (userParams)
184  userParams->setAllDefault(paramNum);
185 
186  switch (bufLength) {
187  case 5: // global correlation
188  if (userParams)
189  userParams->globalCor()[paramNum] = buf[4];
190  [[fallthrough]];
191  case 4: // uncertainty
192  if (userParams)
193  userParams->sigma()[paramNum] = buf[3] / cmsToPede;
194  covMat[paramNum][paramNum] = buf[3] * buf[3] / (cmsToPede * cmsToPede);
195  [[fallthrough]];
196  case 3: // difference to start value
197  if (userParams)
198  userParams->diffBefore()[paramNum] = buf[2] / cmsToPede;
199  [[fallthrough]];
200  case 2:
201  params->setValid(true);
202  parVec[paramNum] = buf[0] / cmsToPede * mySteerer.parameterSign(); // parameter
203  if (userParams) {
204  userParams->parameter()[paramNum] = parVec[paramNum]; // duplicate in millepede parameters
205  userParams->preSigma()[paramNum] = buf[1]; // presigma given, probably means fixed
206  if (!userParams->isFixed(paramNum)) {
207  userParams->preSigma()[paramNum] /= cmsToPede;
208  if (bufLength == 2) {
209  edm::LogWarning("Alignment")
210  << "@SUB=PedeReader::setParameter"
211  << "Param " << paramLabel << " (from " << typeid(*alignable).name() << ") without result!";
212  userParams->isValid()[paramNum] = false;
213  params->setValid(false);
214  }
215  }
216  }
217  break;
218  case 0:
219  case 1:
220  default:
221  edm::LogError("Alignment") << "@SUB=PedeReader::setParameter"
222  << "Expect 2 to 5 values, got " << bufLength << " for label " << paramLabel;
223  break;
224  }
225  alignable->setAlignmentParameters(params->clone(parVec, covMat)); //transferred mem. responsib.
226  } else {
227  unsigned int lasBeamId = myLabels.lasBeamIdFromLabel(paramLabel);
228  edm::LogError("Alignment") << "@SUB=PedeReader::setParameter"
229  << "No alignable for paramLabel " << paramLabel << ", probably LasBeam with Id "
230  << lasBeamId << ",\nparam " << paramNum << ": "
231  << buf[0] / cmsToPede * mySteerer.parameterSign()
232  << " += " << (bufLength >= 4 ? buf[3] / cmsToPede : -99.);
233  }
234 
235  return alignable;
236 }
237 
238 //__________________________________________________________________________________________________
240  unsigned int paramNum,
241  unsigned int bufLength,
242  const float *buf) const {
243  if (!calib || !buf)
244  return false;
245 
246  // FIXME: Should we attach MillePedeVariables to IntegratedCalibrationBase to store
247  // 'other' results beyond value and error?
248  switch (bufLength) {
249  case 5: // buf[4]: global correlation - not treated yet FIXME // no break;
250  case 4: // uncertainty
251  calib->setParameterError(paramNum, buf[3]);
252  [[fallthrough]];
253  case 3: // buf[2]: difference to start value - not treated yet
254  case 2:
255  if (bufLength == 2 && buf[1] >= 0.) { // buf[1]: pre-sigma, < 0 means fixed
256  edm::LogWarning("Alignment") << "@SUB=PedeReader::setCalibrationParameter"
257  << "Param " << paramNum << " of calibration '" << calib->name()
258  << "' without result!";
259  }
260  return calib->setParameter(paramNum, buf[0] * mySteerer.parameterSign());
261  case 0:
262  case 1:
263  default:
264  edm::LogError("Alignment") << "@SUB=PedeReader::setCalibrationParameter"
265  << "Expect 2 to 5 values, got " << bufLength << ".";
266  return false;
267  }
268 }
269 
270 //__________________________________________________________________________________________________
271 AlignmentParameters *PedeReader::checkAliParams(Alignable *alignable, bool createUserVars) const {
272  // first check that we have parameters
274  if (!params) {
275  throw cms::Exception("BadConfig") << "PedeReader::checkAliParams: "
276  << "Alignable without parameters.";
277  }
278 
279  // now check that we have user parameters of correct type if requested:
280  if (createUserVars && !dynamic_cast<MillePedeVariables *>(params->userVariables())) {
281  edm::LogInfo("Alignment") << "@SUB=PedeReader::checkAliParams"
282  << "Add user variables for alignable with label " << myLabels.alignableLabel(alignable);
284  params->size(),
285  myLabels.alignableLabel(alignable),
287  }
288 
289  return params;
290 }
unsigned int label() const
get alignable label as used by pede
const std::vector< float > & globalCor() const
get global correlation array
T getParameter(std::string const &) const
T getUntrackedParameter(std::string const &, T const &) const
virtual const RunRange & runRangeFromLabel(unsigned int label) const
PedeReader(const edm::ParameterSet &config, const PedeSteerer &steerer, const PedeLabelerBase &labels, const RunRange &runrange)
Definition: PedeReader.cc:35
AlignmentParameters * checkAliParams(Alignable *alignable, bool createUserVars) const
Definition: PedeReader.cc:271
std::string typeToName(align::StructureType type) const
Convert type to name.
bool isFixed(unsigned int nParam) const
true if parameter is fixed
const PedeSteerer & mySteerer
Definition: PedeReader.h:71
std::ifstream myPedeResult
Definition: PedeReader.h:70
virtual bool setParameter(unsigned int index, double value)=0
const std::vector< float > & parameter() const
get array of parameters
const std::string & name() const
name of this calibration
Definition: config.py:1
virtual unsigned int paramNumFromLabel(unsigned int paramLabel) const =0
parameter number, 0 <= .. < theMaxNumParam, belonging to unique parameter label
AlignmentParameters * alignmentParameters() const
Get the AlignmentParameters.
Definition: Alignable.h:58
const AlgebraicVector & parameters(void) const
Get alignment parameters.
virtual unsigned int lasBeamIdFromLabel(unsigned int label) const =0
AlignmentUserVariables * userVariables(void) const
Get pointer to user variables.
virtual StructureType alignableObjectId() const =0
Return the alignable type identifier.
void setAlignmentParameters(AlignmentParameters *dap)
Set the AlignmentParameters.
Definition: Alignable.cc:123
void setValid(bool v)
Set validity flag.
const std::vector< float > & preSigma() const
get array of presigmas (<= 0: means fixed)
const std::vector< float > & sigma() const
get array of sigmas
Alignable * setParameter(unsigned int paramLabel, unsigned int bufLength, const float *buf, bool setUserVars) const
Definition: PedeReader.cc:162
bool readIfSameLine(std::ifstream &aStream, T &outValue) const
Definition: PedeReader.cc:130
const AlignableTracker * alignableTracker() const
virtual AlignmentParameters * clone(const AlgebraicVector &par, const AlgebraicSymMatrix &cov) const =0
Enforce clone methods in derived classes.
const AlignableObjectId & objectIdProvider() const
Return tracker alignable object ID provider derived from the tracker&#39;s geometry.
virtual Alignable * alignableFromLabel(unsigned int label) const =0
const std::vector< float > & diffBefore() const
get array of differences to start value
CLHEP::HepVector AlgebraicVector
void setUserVariables(AlignmentUserVariables *auv)
Set pointer to user variables.
int size(void) const
Get number of parameters.
virtual unsigned int alignableLabel(Alignable *alignable) const =0
double cmsToPedeFactor(unsigned int parNum) const
Definition: PedeSteerer.cc:141
PedeLabelerBase::RunRange RunRange
Definition: PedeReader.h:37
const std::vector< bool > & isValid() const
get valid flag array
std::vector< Alignable * > Alignables
Definition: Utilities.h:31
CLHEP::HepSymMatrix AlgebraicSymMatrix
static const unsigned int myMaxNumValPerParam
Definition: PedeReader.h:75
const std::string & directory() const
directory from constructor input, &#39;/&#39; is attached if needed
Definition: PedeSteerer.h:70
virtual bool setParameterError(unsigned int index, double value)=0
virtual std::pair< IntegratedCalibrationBase *, unsigned int > calibrationParamFromLabel(unsigned int label) const
bool setCalibrationParameter(IntegratedCalibrationBase *calib, unsigned int paramNum, unsigned int bufLength, const float *buf) const
Set pede results stored in &#39;buf&#39; to parameter &#39;paramNum&#39; of IntegratedCalibrationBase.
Definition: PedeReader.cc:239
const AlgebraicSymMatrix & covariance(void) const
Get parameter covariance matrix.
long double T
bool read(align::Alignables &alignables, bool setUserVars)
Definition: PedeReader.cc:56
const PedeLabelerBase & myLabels
Definition: PedeReader.h:72
const RunRange myRunRange
Definition: PedeReader.h:73
bool setAllDefault(unsigned int nParam)
set default values for all data concerning nParam (false if nParam out of range)
int parameterSign() const
results from pede (and start values for pede) might need a sign flip
Definition: PedeSteerer.h:68