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