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:
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 {
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);
283  params->setUserVariables(new MillePedeVariables(
284  params->size(),
285  myLabels.alignableLabel(alignable),
287  }
288 
289  return params;
290 }
bool readIfSameLine(std::ifstream &aStream, T &outValue) const
Definition: PedeReader.cc:130
virtual Alignable * alignableFromLabel(unsigned int label) const =0
virtual std::pair< IntegratedCalibrationBase *, unsigned int > calibrationParamFromLabel(unsigned int label) const
AlignmentParameters * alignmentParameters() const
Get the AlignmentParameters.
Definition: Alignable.h:58
PedeReader(const edm::ParameterSet &config, const PedeSteerer &steerer, const PedeLabelerBase &labels, const RunRange &runrange)
Definition: PedeReader.cc:35
const std::vector< float > & preSigma() const
get array of presigmas (<= 0: means fixed)
const PedeSteerer & mySteerer
Definition: PedeReader.h:71
std::ifstream myPedeResult
Definition: PedeReader.h:70
std::string typeToName(align::StructureType type) const
Convert type to name.
virtual unsigned int paramNumFromLabel(unsigned int paramLabel) const =0
parameter number, 0 <= .. < theMaxNumParam, belonging to unique parameter label
const std::vector< bool > & isValid() const
get valid flag array
Definition: config.py:1
Log< level::Error, false > LogError
bool isFixed(unsigned int nParam) const
true if parameter is fixed
int parameterSign() const
results from pede (and start values for pede) might need a sign flip
Definition: PedeSteerer.h:68
unsigned int label() const
get alignable label as used by pede
void setAlignmentParameters(AlignmentParameters *dap)
Set the AlignmentParameters.
Definition: Alignable.cc:123
virtual StructureType alignableObjectId() const =0
Return the alignable type identifier.
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
AlignmentParameters * checkAliParams(Alignable *alignable, bool createUserVars) const
Definition: PedeReader.cc:271
const std::vector< float > & diffBefore() const
get array of differences to start value
Log< level::Info, false > LogInfo
CLHEP::HepVector AlgebraicVector
virtual unsigned int alignableLabel(const Alignable *alignable) const =0
const std::vector< float > & sigma() const
get array of sigmas
PedeLabelerBase::RunRange RunRange
Definition: PedeReader.h:37
const std::string & directory() const
directory from constructor input, &#39;/&#39; is attached if needed
Definition: PedeSteerer.h:70
std::vector< Alignable * > Alignables
Definition: Utilities.h:31
const AlignableTracker * alignableTracker() const
virtual const RunRange & runRangeFromLabel(unsigned int label) const
CLHEP::HepSymMatrix AlgebraicSymMatrix
static const unsigned int myMaxNumValPerParam
Definition: PedeReader.h:75
const AlignableObjectId & objectIdProvider() const
Return tracker alignable object ID provider derived from the tracker&#39;s geometry.
Alignable * setParameter(unsigned int paramLabel, unsigned int bufLength, const float *buf, bool setUserVars) const
Definition: PedeReader.cc:162
const std::vector< float > & parameter() const
get array of parameters
Log< level::Warning, false > LogWarning
long double T
bool read(align::Alignables &alignables, bool setUserVars)
Definition: PedeReader.cc:56
const std::vector< float > & globalCor() const
get global correlation array
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)
double cmsToPedeFactor(unsigned int parNum) const
Definition: PedeSteerer.cc:149
virtual unsigned int lasBeamIdFromLabel(unsigned int label) const =0