00001
00011 #include "PedeReader.h"
00012 #include "PedeSteerer.h"
00013 #include "PedeLabeler.h"
00014
00015 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00016 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00017
00018 #include "Alignment/CommonAlignment/interface/Alignable.h"
00019 #include "Alignment/CommonAlignment/interface/AlignmentParameters.h"
00020
00021 #include "Alignment/CommonAlignmentParametrization/interface/RigidBodyAlignmentParameters.h"
00022
00023 #include "Alignment/MillePedeAlignmentAlgorithm/interface/MillePedeVariables.h"
00024
00025 #include <map>
00026 #include <string>
00027
00028
00029 const unsigned int PedeReader::myMaxNumValPerParam = 5;
00030
00031
00032 PedeReader::PedeReader(const edm::ParameterSet &config, const PedeSteerer &steerer,
00033 const PedeLabeler &labels)
00034 : mySteerer(steerer), myLabels(labels)
00035 {
00036 std::string pedeResultFile(config.getUntrackedParameter<std::string>("fileDir"));
00037 if (pedeResultFile.empty()) pedeResultFile = steerer.directory();
00038 else if (pedeResultFile.find_last_of('/') != pedeResultFile.size() - 1) {
00039 pedeResultFile += '/';
00040 }
00041
00042 pedeResultFile += config.getParameter<std::string>("readFile");
00043 myPedeResult.open(pedeResultFile.c_str(), std::ios::in);
00044 if (!myPedeResult.is_open()) {
00045 edm::LogError("Alignment") << "@SUB=PedeReader"
00046 << "Problem opening pede output file " << pedeResultFile;
00047 }
00048 }
00049
00050
00051 bool PedeReader::read(std::vector<Alignable*> &alignables, bool setUserVars)
00052 {
00053 alignables.clear();
00054 myPedeResult.seekg(0, std::ios::beg);
00055 bool isAllOk = true;
00056
00057 std::map<Alignable*,Alignable*> uniqueList;
00058
00059
00060 unsigned int nParam = 0;
00061 while (myPedeResult.good() && !myPedeResult.eof()) {
00062
00063 unsigned int paramLabel = 0;
00064 if (!this->readIfSameLine<unsigned int>(myPedeResult, paramLabel)) continue;
00065
00066
00067 float buffer[myMaxNumValPerParam] = {0.};
00068 unsigned int bufferPos = 0;
00069 for ( ; bufferPos < myMaxNumValPerParam; ++bufferPos) {
00070 if (!this->readIfSameLine<float>(myPedeResult, buffer[bufferPos])) break;
00071 }
00072
00073 Alignable *alignable = this->setParameter(paramLabel, bufferPos, buffer, setUserVars);
00074 if (!alignable) {
00075 isAllOk = false;
00076 continue;
00077 }
00078 uniqueList[alignable] = alignable;
00079 ++nParam;
00080 }
00081
00082
00083 for ( std::map<Alignable*,Alignable*>::const_iterator iAli = uniqueList.begin();
00084 iAli != uniqueList.end(); ++iAli) {
00085 alignables.push_back((*iAli).first);
00086 }
00087
00088 edm::LogInfo("Alignment") << "@SUB=PedeReader::read" << nParam << " parameters for "
00089 << alignables.size() << " alignables";
00090
00091 return isAllOk && nParam;
00092 }
00093
00094
00095
00096 template<class T>
00097 bool PedeReader::readIfSameLine(std::ifstream &aStream, T &outValue) const
00098 {
00099
00100 while (true) {
00101 const int aChar = aStream.get();
00102 if (!aStream.good()) return false;
00103
00104 switch(aChar) {
00105 case ' ':
00106 case '\t':
00107 continue;
00108 case '\n':
00109 return false;
00110 default:
00111 aStream.unget();
00112 aStream >> outValue;
00113 if (aStream.fail()) {
00114 aStream.clear();
00115 while (aStream.good() && aStream.get() != '\n');
00116 return false;
00117 } else {
00118 return true;
00119 }
00120 }
00121 }
00122
00123 edm::LogError("Alignment") << "@SUB=PedeReader::readIfSameLine" << "Should never come here!";
00124 return false;
00125 }
00126
00127
00128 Alignable* PedeReader::setParameter(unsigned int paramLabel,
00129 unsigned int bufLength, float *buf, bool setUserVars) const
00130 {
00131 Alignable *alignable = myLabels.alignableFromLabel(paramLabel);
00132 if (alignable) {
00133 AlignmentParameters *params = this->checkAliParams(alignable, setUserVars);
00134 MillePedeVariables *userParams =
00135 (setUserVars ? static_cast<MillePedeVariables*>(params->userVariables()) : 0);
00136 if (userParams) userParams->setLabel(myLabels.alignableLabelFromLabel(paramLabel));
00137
00138 AlgebraicVector parVec(params->parameters());
00139 AlgebraicSymMatrix covMat(params->covariance());
00140 const unsigned int paramNum = myLabels.paramNumFromLabel(paramLabel);
00141
00142 if (userParams) userParams->setAllDefault(paramNum);
00143 const double cmsToPede = mySteerer.cmsToPedeFactor(paramNum);
00144
00145 switch (bufLength) {
00146 case 5:
00147 if (userParams) userParams->globalCor()[paramNum] = buf[4];
00148 case 4:
00149 if (userParams) userParams->sigma()[paramNum] = buf[3] / cmsToPede;
00150 covMat[paramNum][paramNum] = buf[3]*buf[3] / (cmsToPede*cmsToPede);
00151
00152 case 3:
00153 if (userParams) userParams->diffBefore()[paramNum] = buf[2] / cmsToPede;
00154
00155 case 2:
00156 parVec[paramNum] = buf[0] / cmsToPede * mySteerer.parameterSign();
00157 if (userParams) {
00158 userParams->parameter()[paramNum] = parVec[paramNum];
00159 userParams->preSigma()[paramNum] = buf[1];
00160 if (!userParams->isFixed(paramNum)) {
00161 userParams->preSigma()[paramNum] /= cmsToPede;
00162 if (bufLength == 2) {
00163 edm::LogError("Alignment") << "@SUB=PedeReader::setParameter"
00164 << "Param " << paramLabel << " (from "
00165 << typeid(*alignable).name() << ") without result!";
00166 userParams->isValid()[paramNum] = false;
00167 }
00168 }
00169 }
00170 break;
00171 case 0:
00172 case 1:
00173 default:
00174 edm::LogError("Alignment") << "@SUB=PedeReader::setParameter"
00175 << "Expect 2 to 5 values, got " << bufLength
00176 << " for label " << paramLabel;
00177 break;
00178 }
00179 alignable->setAlignmentParameters(params->clone(parVec, covMat));
00180 }
00181 return alignable;
00182 }
00183
00184
00185 AlignmentParameters* PedeReader::checkAliParams(Alignable *alignable, bool createUserVars) const
00186 {
00187
00188 AlignmentParameters *params = alignable->alignmentParameters();
00189 if (!params) {
00190
00191 params = new RigidBodyAlignmentParameters(alignable, false);
00192
00193 edm::LogInfo("Alignment") << "@SUB=PedeReader::checkAliParams"
00194 << "Build RigidBodyAlignmentParameters for alignable with label "
00195 << myLabels.alignableLabel(alignable);
00196 alignable->setAlignmentParameters(params);
00197 }
00198
00199
00200 if (createUserVars && !dynamic_cast<MillePedeVariables*>(params->userVariables())) {
00201 edm::LogInfo("Alignment") << "@SUB=PedeReader::checkAliParams"
00202 << "Add user variables for alignable with label "
00203 << myLabels.alignableLabel(alignable);
00204 params->setUserVariables(new MillePedeVariables(params->size()));
00205 }
00206
00207 return params;
00208 }