CMS 3D CMS Logo

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