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