CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
MillePedeAlignmentAlgorithm.cc
Go to the documentation of this file.
1 
12 //#include "MillePedeAlignmentAlgorithm.h"
13 
17 
19 // in header, too
20 // end in header, too
21 
25 #include "Mille.h" // 'unpublished' interface located in src
26 #include "PedeSteerer.h" // dito
27 #include "PedeReader.h" // dito
30 
33 
37 
41 
42 // includes to make known that they inherit from Alignable:
46 
52 
57 
59 
60 #include <fstream>
61 #include <sstream>
62 #include <algorithm>
63 
64 #include <TMath.h>
65 #include <TMatrixDSymEigen.h>
69 
70 // Includes for PXB survey
71 #include <iostream>
78 
80 
81 // Constructor ----------------------------------------------------------------
82 //____________________________________________________
85  theConfig(cfg), theMode(this->decodeMode(theConfig.getUntrackedParameter<std::string>("mode"))),
86  theDir(theConfig.getUntrackedParameter<std::string>("fileDir")),
87  theAlignmentParameterStore(0), theAlignables(), theAlignableNavigator(0),
88  theMonitor(0), theMille(0), thePedeLabels(0), thePedeSteer(0),
89  theTrajectoryFactory(0),
90  theMinNumHits(cfg.getParameter<unsigned int>("minNumHits")),
91  theMaximalCor2D(cfg.getParameter<double>("max2Dcorrelation")),
92  theLastWrittenIov(0)
93 {
94  if (!theDir.empty() && theDir.find_last_of('/') != theDir.size()-1) theDir += '/';// may need '/'
95  edm::LogInfo("Alignment") << "@SUB=MillePedeAlignmentAlgorithm" << "Start in mode '"
97  << "' with output directory '" << theDir << "'.";
98  if (this->isMode(myMilleBit)) {
99  theMille = new Mille((theDir + theConfig.getParameter<std::string>("binaryFile")).c_str());// add ', false);' for text output);
100  }
101 }
102 
103 // Destructor ----------------------------------------------------------------
104 //____________________________________________________
106 {
107  delete theAlignableNavigator;
109  delete theMille;
110  theMille = 0;
111  delete theMonitor;
112  theMonitor = 0;
113  delete thePedeSteer;
114  thePedeSteer = 0;
115  delete thePedeLabels;
116  thePedeLabels = 0;
117  delete theTrajectoryFactory;
119 }
120 
121 // Call at beginning of job ---------------------------------------------------
122 //____________________________________________________
126 {
127  if (muon) {
128  edm::LogWarning("Alignment") << "@SUB=MillePedeAlignmentAlgorithm::initialize"
129  << "Running with AlignabeMuon not yet tested.";
130  }
131 
132  //Retrieve tracker topology from geometry
133  edm::ESHandle<TrackerTopology> tTopoHandle;
134  setup.get<IdealGeometryRecord>().get(tTopoHandle);
135  const TrackerTopology* const tTopo = tTopoHandle.product();
136 
137  theAlignableNavigator = new AlignableNavigator(extras, tracker, muon);
140 
141  edm::ParameterSet pedeLabelerCfg(theConfig.getParameter<edm::ParameterSet>("pedeLabeler"));
142  edm::VParameterSet RunRangeSelectionVPSet(theConfig.getUntrackedParameter<edm::VParameterSet>("RunRangeSelection"));
143  pedeLabelerCfg.addUntrackedParameter<edm::VParameterSet>("RunRangeSelection",
144  RunRangeSelectionVPSet);
145 
146  std::string labelerPlugin = "PedeLabeler";
147  if (RunRangeSelectionVPSet.size()>0) {
148  labelerPlugin = "RunRangeDependentPedeLabeler";
149  if (pedeLabelerCfg.exists("plugin")) {
150  std::string labelerPluginCfg = pedeLabelerCfg.getParameter<std::string>("plugin");
151  if ((labelerPluginCfg!="PedeLabeler" && labelerPluginCfg!="RunRangeDependentPedeLabeler") ||
152  pedeLabelerCfg.getUntrackedParameter<edm::VParameterSet>("parameterInstances").size()>0) {
153  throw cms::Exception("BadConfig")
154  << "MillePedeAlignmentAlgorithm::initialize"
155  << "both RunRangeSelection and generic labeler specified in config file. "
156  << "Please get rid of either one of them.\n";
157  }
158  }
159  } else {
160  if (pedeLabelerCfg.exists("plugin")) {
161  labelerPlugin = pedeLabelerCfg.getParameter<std::string>("plugin");
162  }
163  }
164 
165  if (!pedeLabelerCfg.exists("plugin")) {
166  pedeLabelerCfg.addUntrackedParameter<std::string>("plugin", labelerPlugin);
167  }
168 
169  edm::LogInfo("Alignment") << "@SUB=MillePedeAlignmentAlgorithm::initialize"
170  << "Using plugin '" << labelerPlugin << "' to generate labels.";
171 
172  thePedeLabels = PedeLabelerPluginFactory::get()->create(labelerPlugin,
173  PedeLabelerBase::TopLevelAlignables(tracker, muon, extras),
174  pedeLabelerCfg);
175 
176  // 1) Create PedeSteerer: correct alignable positions for coordinate system selection
177  edm::ParameterSet pedeSteerCfg(theConfig.getParameter<edm::ParameterSet>("pedeSteerer"));
178  thePedeSteer = new PedeSteerer(tracker, muon, extras,
180  pedeSteerCfg, theDir, !this->isMode(myPedeSteerBit));
181 
182  // 2) If requested, directly read in and apply result of previous pede run,
183  // assuming that correction from 1) was also applied to create the result:
184  const std::vector<edm::ParameterSet> mprespset
185  (theConfig.getParameter<std::vector<edm::ParameterSet> >("pedeReaderInputs"));
186  if (!mprespset.empty()) {
187  edm::LogInfo("Alignment") << "@SUB=MillePedeAlignmentAlgorithm::initialize"
188  << "Apply " << mprespset.end() - mprespset.begin()
189  << " previous MillePede constants from 'pedeReaderInputs'.";
190  }
191 
192  // FIXME: add selection of run range via 'pedeReaderInputs'
193  // Note: Results for parameters of IntegratedCalibration's cannot be treated...
194  RunRange runrange(cond::timeTypeSpecs[cond::runnumber].beginValue,
196  for (std::vector<edm::ParameterSet>::const_iterator iSet = mprespset.begin(), iE = mprespset.end();
197  iSet != iE; ++iSet) {
198  // This read will ignore calibrations as long as they are not yet passed to Millepede
199  // during/before initialize(..) - currently addCalibrations(..) is called later in AlignmentProducer
200  if (!this->readFromPede((*iSet), false, runrange)) { // false: do not erase SelectionUserVariables
201  throw cms::Exception("BadConfig")
202  << "MillePedeAlignmentAlgorithm::initialize: Problems reading input constants of "
203  << "pedeReaderInputs entry " << iSet - mprespset.begin() << '.';
204  }
206  // Needed to shut up later warning from checkAliParams:
208  }
209 
210  // 3) Now create steerings with 'final' start position:
211  thePedeSteer->buildSubSteer(tracker, muon, extras);
212 
213  // After (!) 1-3 of PedeSteerer which uses the SelectionUserVariables attached to the parameters:
214  this->buildUserVariables(theAlignables); // for hit statistics and/or pede result
215 
216  if (this->isMode(myMilleBit)) {
217  if (!theConfig.getParameter<std::vector<std::string> >("mergeBinaryFiles").empty() ||
218  !theConfig.getParameter<std::vector<std::string> >("mergeTreeFiles").empty()) {
219  throw cms::Exception("BadConfig")
220  << "'vstring mergeTreeFiles' and 'vstring mergeBinaryFiles' must be empty for "
221  << "modes running mille.";
222  }
223  const std::string moniFile(theConfig.getUntrackedParameter<std::string>("monitorFile"));
224  if (moniFile.size()) theMonitor = new MillePedeMonitor(tTopo, (theDir + moniFile).c_str());
225 
226  // Get trajectory factory. In case nothing found, FrameWork will throw...
227  const edm::ParameterSet fctCfg(theConfig.getParameter<edm::ParameterSet>("TrajectoryFactory"));
228  const std::string fctName(fctCfg.getParameter<std::string>("TrajectoryFactoryName"));
229  theTrajectoryFactory = TrajectoryFactoryPlugin::get()->create(fctName, fctCfg);
230  }
231 
232  if (this->isMode(myPedeSteerBit)) {
233  // Get config for survey and set flag accordingly
234  const edm::ParameterSet pxbSurveyCfg(theConfig.getParameter<edm::ParameterSet>("surveyPixelBarrel"));
235  theDoSurveyPixelBarrel = pxbSurveyCfg.getParameter<bool>("doSurvey");
236  if (theDoSurveyPixelBarrel) this->addPxbSurvey(pxbSurveyCfg);
237  }
238 }
239 
240 //____________________________________________________
241 bool MillePedeAlignmentAlgorithm::addCalibrations(const std::vector<IntegratedCalibrationBase*> &iCals)
242 {
243  theCalibrations.insert(theCalibrations.end(), iCals.begin(), iCals.end());
245  return true;
246 }
247 
248 //____________________________________________________
250 {
251  if (this->isMode(myPedeReadBit)) {
252  // restore initial positions, rotations and deformations
254 
255  // Needed to shut up later warning from checkAliParams:
257  // To avoid that they keep values from previous IOV if no new one in pede result
259 
260  if (!this->readFromPede(theConfig.getParameter<edm::ParameterSet>("pedeReader"), true, runrange)) {
261  edm::LogError("Alignment") << "@SUB=MillePedeAlignmentAlgorithm::setParametersForRunRange"
262  << "Problems reading pede result, but applying!";
263  }
265 
266  this->doIO(++theLastWrittenIov); // pre-increment!
267  }
268 
269  return true;
270 }
271 
272 // Call at end of job ---------------------------------------------------------
273 //____________________________________________________
275 {
276  delete theMille;// delete to close binary before running pede below (flush would be enough...)
277  theMille = 0;
278 
279  std::vector<std::string> files;
280  if (this->isMode(myMilleBit) || !theConfig.getParameter<std::string>("binaryFile").empty()) {
281  files.push_back(theDir + theConfig.getParameter<std::string>("binaryFile"));
282  } else {
283  const std::vector<std::string> plainFiles
284  (theConfig.getParameter<std::vector<std::string> >("mergeBinaryFiles"));
285  for (std::vector<std::string>::const_iterator i = plainFiles.begin(), iEnd = plainFiles.end();
286  i != iEnd; ++i) {
287  files.push_back(theDir + *i);
288  }
289  }
290 
291  // cache all positions, rotations and deformations
293 
294  const std::string masterSteer(thePedeSteer->buildMasterSteer(files));// do only if myPedeSteerBit?
295  if (this->isMode(myPedeRunBit)) {
296  thePedeSteer->runPede(masterSteer);
297  }
298 
299  // parameters from pede are not yet applied,
300  // so we can still write start positions (but with hit statistics in case of mille):
301  this->doIO(0);
302  theLastWrittenIov = 0;
303 }
304 
305 // Run the algorithm on trajectories and tracks -------------------------------
306 //____________________________________________________
308 {
309  if (!this->isMode(myMilleBit)) return; // no theMille created...
311 
312  if (theMonitor) { // monitor input tracks
313  for (ConstTrajTrackPairCollection::const_iterator iTrajTrack = tracks.begin();
314  iTrajTrack != tracks.end(); ++iTrajTrack) {
315  theMonitor->fillTrack((*iTrajTrack).second);
316  }
317  }
318 
319  const RefTrajColl trajectories(theTrajectoryFactory->trajectories(setup, tracks, eventInfo.beamSpot_));
320 
321  // Now loop over ReferenceTrajectoryCollection
322  unsigned int refTrajCount = 0; // counter for track monitoring if 1 track per trajectory
323  for (RefTrajColl::const_iterator iRefTraj = trajectories.begin(), iRefTrajE = trajectories.end();
324  iRefTraj != iRefTrajE; ++iRefTraj, ++refTrajCount) {
325 
326  RefTrajColl::value_type refTrajPtr = *iRefTraj;
327  if (theMonitor) theMonitor->fillRefTrajectory(refTrajPtr);
328 
329  const std::pair<unsigned int, unsigned int> nHitXy
330  = this->addReferenceTrajectory(setup, eventInfo, refTrajPtr);
331 
332  if (theMonitor && (nHitXy.first || nHitXy.second)) {
333  // if track used (i.e. some hits), fill monitoring
334  // track NULL ptr if trajectories and tracks do not match
335  const reco::Track *trackPtr =
336  (trajectories.size() == tracks.size() ? tracks[refTrajCount].second : 0);
337  theMonitor->fillUsedTrack(trackPtr, nHitXy.first, nHitXy.second);
338  }
339 
340  } // end of reference trajectory and track loop
341 }
342 
343 
344 //____________________________________________________
345 std::pair<unsigned int, unsigned int>
347  const EventInfo &eventInfo,
348  const RefTrajColl::value_type &refTrajPtr)
349 {
350  std::pair<unsigned int, unsigned int> hitResultXy(0,0);
351  if (refTrajPtr->isValid()) {
352 
353  // to add hits if all fine:
354  std::vector<AlignmentParameters*> parVec(refTrajPtr->recHits().size());
355  // collect hit statistics, assuming that there are no y-only hits
356  std::vector<bool> validHitVecY(refTrajPtr->recHits().size(), false);
357  // Use recHits from ReferenceTrajectory (since they have the right order!):
358  for (unsigned int iHit = 0; iHit < refTrajPtr->recHits().size(); ++iHit) {
359  const int flagXY = this->addMeasurementData(setup, eventInfo, refTrajPtr, iHit, parVec[iHit]);
360 
361  if (flagXY < 0) { // problem
362  hitResultXy.first = 0;
363  break;
364  } else { // hit is fine, increase x/y statistics
365  if (flagXY >= 1) ++hitResultXy.first;
366  validHitVecY[iHit] = (flagXY >= 2);
367  }
368  } // end loop on hits
369 
370  // add virtual measurements
371  for (unsigned int iVirtualMeas = 0; iVirtualMeas < refTrajPtr->numberOfVirtualMeas(); ++iVirtualMeas) {
372  this->addVirtualMeas(refTrajPtr, iVirtualMeas);
373  }
374 
375  // kill or end 'track' for mille, depends on #hits criterion
376  if (hitResultXy.first == 0 || hitResultXy.first < theMinNumHits) {
377  theMille->kill();
378  hitResultXy.first = hitResultXy.second = 0; //reset
379  } else {
380  theMille->end();
381  // add x/y hit count to MillePedeVariables of parVec,
382  // returning number of y-hits of the reference trajectory
383  hitResultXy.second = this->addHitCount(parVec, validHitVecY);
384  }
385  } // end if valid trajectory
386 
387  return hitResultXy;
388 }
389 
390 //____________________________________________________
391 unsigned int
392 MillePedeAlignmentAlgorithm::addHitCount(const std::vector<AlignmentParameters*> &parVec,
393  const std::vector<bool> &validHitVecY) const
394 {
395  // Loop on all hit information in the input arrays and count valid y-hits:
396  unsigned int nHitY = 0;
397  for (unsigned int iHit = 0; iHit < validHitVecY.size(); ++iHit) {
398  Alignable *ali = (parVec[iHit] ? parVec[iHit]->alignable() : 0);
399  // Loop upwards on hierarchy of alignables to add hits to all levels
400  // that are currently aligned. If only a non-selected alignable was hit,
401  // (i.e. flagXY == 0 in addReferenceTrajectory(..)), there is no loop at all...
402  while (ali) {
404  if (pars) { // otherwise hierarchy level not selected
405  // cast ensured by previous checks:
406  MillePedeVariables *mpVar = static_cast<MillePedeVariables*>(pars->userVariables());
407  // every hit has an x-measurement, cf. addReferenceTrajectory(..):
408  mpVar->increaseHitsX();
409  if (validHitVecY[iHit]) {
410  mpVar->increaseHitsY();
411  if (pars == parVec[iHit]) ++nHitY; // do not count hits twice
412  }
413  }
414  ali = ali->mother();
415  }
416  }
417 
418  return nHitY;
419 }
420 
421 //____________________________________________________
423  const edm::EventSetup &setup)
424 {
425  if(runInfo.tkLasBeams_ && runInfo.tkLasBeamTsoses_){
426  // LAS beam treatment
427  this->addLaserData(eventInfo, *(runInfo.tkLasBeams_), *(runInfo.tkLasBeamTsoses_));
428  }
429 }
430 
431 //____________________________________________________
433  const EventInfo &eventInfo,
435  unsigned int iHit,
436  AlignmentParameters *&params)
437 {
438  params = 0;
439  theFloatBufferX.clear();
440  theFloatBufferY.clear();
441  theIntBuffer.clear();
442 
443  const TrajectoryStateOnSurface &tsos = refTrajPtr->trajectoryStates()[iHit];
444  const ConstRecHitPointer &recHitPtr = refTrajPtr->recHits()[iHit];
445  // ignore invalid hits
446  if (!recHitPtr->isValid()) return 0;
447 
448  // First add the derivatives from IntegratedCalibration's,
449  // should even be OK if problems for "usual" derivatives from Alignables
450  this->globalDerivativesCalibration(recHitPtr, tsos, setup, eventInfo, // input
452 
453  // get AlignableDet/Unit for this hit
454  AlignableDetOrUnitPtr alidet(theAlignableNavigator->alignableFromDetId(recHitPtr->geographicalId()));
455 
456  if (!this->globalDerivativesHierarchy(eventInfo,
457  tsos, alidet, alidet, theFloatBufferX, // 2x alidet, sic!
458  theFloatBufferY, theIntBuffer, params)) {
459  return -1; // problem
460  } else if (theFloatBufferX.empty()) {
461  return 0; // empty for X: no alignable for hit, nor calibrations
462  } else { // now even if no alignable, but calibrations!
463  return this->callMille(refTrajPtr, iHit, theIntBuffer, theFloatBufferX, theFloatBufferY);
464  }
465 }
466 
467 //____________________________________________________
470  const TrajectoryStateOnSurface &tsos,
471  Alignable *ali, const AlignableDetOrUnitPtr &alidet,
472  std::vector<float> &globalDerivativesX,
473  std::vector<float> &globalDerivativesY,
474  std::vector<int> &globalLabels,
475  AlignmentParameters *&lowestParams) const
476 {
477  // derivatives and labels are recursively attached
478  if (!ali) return true; // no mother might be OK
479 
480  if (false && theMonitor && alidet != ali) theMonitor->fillFrameToFrame(alidet, ali);
481 
482  AlignmentParameters *params = ali->alignmentParameters();
483 
484  if (params) {
485  if (!lowestParams) lowestParams = params; // set parameters of lowest level
486 
487  bool hasSplitParameters = thePedeLabels->hasSplitParameters(ali);
488  const unsigned int alignableLabel = thePedeLabels->alignableLabel(ali);
489 
490  if (0 == alignableLabel) { // FIXME: what about regardAllHits in Markus' code?
491  edm::LogWarning("Alignment") << "@SUB=MillePedeAlignmentAlgorithm::globalDerivativesHierarchy"
492  << "Label not found, skip Alignable.";
493  return false;
494  }
495 
496  const std::vector<bool> &selPars = params->selector();
497  const AlgebraicMatrix derivs(params->derivatives(tsos, alidet));
498 
499  // cols: 2, i.e. x&y, rows: parameters, usually RigidBodyAlignmentParameters::N_PARAM
500  for (unsigned int iSel = 0; iSel < selPars.size(); ++iSel) {
501  if (selPars[iSel]) {
502  globalDerivativesX.push_back(derivs[iSel][kLocalX]
503  /thePedeSteer->cmsToPedeFactor(iSel));
504  if (hasSplitParameters==true) {
505  globalLabels.push_back(thePedeLabels->parameterLabel(ali, iSel, eventInfo, tsos));
506  } else {
507  globalLabels.push_back(thePedeLabels->parameterLabel(alignableLabel, iSel));
508  }
509  globalDerivativesY.push_back(derivs[iSel][kLocalY]
510  /thePedeSteer->cmsToPedeFactor(iSel));
511  }
512  }
513  // Exclude mothers if Alignable selected to be no part of a hierarchy:
514  if (thePedeSteer->isNoHiera(ali)) return true;
515  }
516  // Call recursively for mother, will stop if mother == 0:
517  return this->globalDerivativesHierarchy(eventInfo,
518  tsos, ali->mother(), alidet,
519  globalDerivativesX, globalDerivativesY,
520  globalLabels, lowestParams);
521 }
522 
523 
524 //____________________________________________________
527  const TrajectoryStateOnSurface &tsos,
528  const edm::EventSetup &setup, const EventInfo &eventInfo,
529  std::vector<float> &globalDerivativesX,
530  std::vector<float> &globalDerivativesY,
531  std::vector<int> &globalLabels) const
532 {
533  std::vector<IntegratedCalibrationBase::ValuesIndexPair> derivs;
534  for (auto iCalib = theCalibrations.begin(); iCalib != theCalibrations.end(); ++iCalib) {
535  // get all derivatives of this calibration // const unsigned int num =
536  (*iCalib)->derivatives(derivs, *recHit, tsos, setup, eventInfo);
537  for (auto iValuesInd = derivs.begin(); iValuesInd != derivs.end(); ++iValuesInd) {
538  // transfer label and x/y derivatives
539  globalLabels.push_back(thePedeLabels->calibrationLabel(*iCalib, iValuesInd->second));
540  globalDerivativesX.push_back(iValuesInd->first.first);
541  globalDerivativesY.push_back(iValuesInd->first.second);
542  }
543  }
544 }
545 
546 // //____________________________________________________
547 // void MillePedeAlignmentAlgorithm
548 // ::callMille(const ReferenceTrajectoryBase::ReferenceTrajectoryPtr &refTrajPtr,
549 // unsigned int iTrajHit, MeasurementDirection xOrY,
550 // const std::vector<float> &globalDerivatives, const std::vector<int> &globalLabels)
551 // {
552 // const unsigned int xyIndex = iTrajHit*2 + xOrY;
553 // // FIXME: here for residuum and sigma we could use KALMAN-Filter results
554 // const float residuum =
555 // refTrajPtr->measurements()[xyIndex] - refTrajPtr->trajectoryPositions()[xyIndex];
556 // const float covariance = refTrajPtr->measurementErrors()[xyIndex][xyIndex];
557 // const float sigma = (covariance > 0. ? TMath::Sqrt(covariance) : 0.);
558 
559 // const AlgebraicMatrix &locDerivMatrix = refTrajPtr->derivatives();
560 
561 // std::vector<float> localDerivs(locDerivMatrix.num_col());
562 // for (unsigned int i = 0; i < localDerivs.size(); ++i) {
563 // localDerivs[i] = locDerivMatrix[xyIndex][i];
564 // }
565 
566 // // &(vector[0]) is valid - as long as vector is not empty
567 // // cf. http://www.parashift.com/c++-faq-lite/containers.html#faq-34.3
568 // theMille->mille(localDerivs.size(), &(localDerivs[0]),
569 // globalDerivatives.size(), &(globalDerivatives[0]), &(globalLabels[0]),
570 // residuum, sigma);
571 // if (theMonitor) {
572 // theMonitor->fillDerivatives(refTrajPtr->recHits()[iTrajHit],localDerivs, globalDerivatives,
573 // (xOrY == kLocalY));
574 // theMonitor->fillResiduals(refTrajPtr->recHits()[iTrajHit],
575 // refTrajPtr->trajectoryStates()[iTrajHit],
576 // iTrajHit, residuum, sigma, (xOrY == kLocalY));
577 // }
578 // }
579 
580 //____________________________________________________
582 {
583  // FIXME: Check whether this is a reliable and recommended way to find out...
584 
585  if (recHit->dimension() < 2) {
586  return false; // some muon and TIB/TOB stuff really has RecHit1D
587  } else if (recHit->detUnit()) { // detunit in strip is 1D, in pixel 2D
588  return recHit->detUnit()->type().isTrackerPixel();
589  } else { // stereo strips (FIXME: endcap trouble due to non-parallel strips (wedge sensors)?)
590  if (dynamic_cast<const ProjectedSiStripRecHit2D*>(recHit->hit())) { // check persistent hit
591  // projected: 1D measurement on 'glued' module
592  return false;
593  } else {
594  return true;
595  }
596  }
597 }
598 
599 //__________________________________________________________________________________________________
600 bool MillePedeAlignmentAlgorithm::readFromPede(const edm::ParameterSet &mprespset, bool setUserVars,
601  const RunRange &runrange)
602 {
603  bool allEmpty = this->areEmptyParams(theAlignables);
604 
605  PedeReader reader(mprespset, *thePedeSteer, *thePedeLabels, runrange);
606  std::vector<Alignable*> alis;
607  bool okRead = reader.read(alis, setUserVars); // also may set params of IntegratedCalibration's
608  bool numMatch = true;
609 
610  std::stringstream out;
611  out << "Read " << alis.size() << " alignables";
612  if (alis.size() != theAlignables.size()) {
613  out << " while " << theAlignables.size() << " in store";
614  numMatch = false; // FIXME: Should we check one by one? Or transfer 'alis' to the store?
615  }
616  if (!okRead) out << ", but problems in reading";
617  if (!allEmpty) out << ", possibly overwriting previous settings";
618  out << ".";
619 
620  if (okRead && allEmpty) {
621  if (numMatch) { // as many alignables with result as trying to align
622  edm::LogInfo("Alignment") << "@SUB=MillePedeAlignmentAlgorithm::readFromPede" << out.str();
623  } else if (alis.size()) { // dead module do not get hits and no pede result
624  edm::LogWarning("Alignment") << "@SUB=MillePedeAlignmentAlgorithm::readFromPede" << out.str();
625  } else { // serious problem: no result read - and not all modules can be dead...
626  edm::LogError("Alignment") << "@SUB=MillePedeAlignmentAlgorithm::readFromPede" << out.str();
627  return false;
628  }
629  return true;
630  }
631  // the rest is not OK:
632  edm::LogError("Alignment") << "@SUB=MillePedeAlignmentAlgorithm::readFromPede" << out.str();
633  return false;
634 }
635 
636 //__________________________________________________________________________________________________
637 bool MillePedeAlignmentAlgorithm::areEmptyParams(const std::vector<Alignable*> &alignables) const
638 {
639 
640  for (std::vector<Alignable*>::const_iterator iAli = alignables.begin();
641  iAli != alignables.end(); ++iAli) {
642  const AlignmentParameters *params = (*iAli)->alignmentParameters();
643  if (params) {
644  const AlgebraicVector &parVec(params->parameters());
645  const AlgebraicMatrix &parCov(params->covariance());
646  for (int i = 0; i < parVec.num_row(); ++i) {
647  if (parVec[i] != 0.) return false;
648  for (int j = i; j < parCov.num_col(); ++j) {
649  if (parCov[i][j] != 0.) return false;
650  }
651  }
652  }
653  }
654 
655  return true;
656 }
657 
658 //__________________________________________________________________________________________________
660 {
661  unsigned int result = 0;
662 
663  const std::string outFilePlain(theConfig.getParameter<std::string>("treeFile"));
664  if (outFilePlain.empty()) {
665  edm::LogInfo("Alignment") << "@SUB=MillePedeAlignmentAlgorithm::doIO"
666  << "treeFile parameter empty => skip writing for 'loop' " << loop;
667  return result;
668  }
669 
670  const std::string outFile(theDir + outFilePlain);
671 
672  AlignmentIORoot aliIO;
673  int ioerr = 0;
674  if (loop == 0) {
675  aliIO.writeAlignableOriginalPositions(theAlignables, outFile.c_str(), loop, false, ioerr);
676  if (ioerr) {
677  edm::LogError("Alignment") << "@SUB=MillePedeAlignmentAlgorithm::doIO"
678  << "Problem " << ioerr << " in writeAlignableOriginalPositions";
679  ++result;
680  }
681  } else if (loop == 1) {
682  // only for first iov add hit counts, else 2x, 3x,... number of hits in IOV 2, 3,...
683  const std::vector<std::string> inFiles
684  (theConfig.getParameter<std::vector<std::string> >("mergeTreeFiles"));
685  const std::vector<std::string> binFiles
686  (theConfig.getParameter<std::vector<std::string> >("mergeBinaryFiles"));
687  if (inFiles.size() != binFiles.size()) {
688  edm::LogWarning("Alignment") << "@SUB=MillePedeAlignmentAlgorithm::doIO"
689  << "'vstring mergeTreeFiles' and 'vstring mergeBinaryFiles' "
690  << "differ in size";
691  }
692  this->addHitStatistics(0, outFile, inFiles); // add hit info from tree 0 in 'infiles'
693  }
694  MillePedeVariablesIORoot millePedeIO;
695  millePedeIO.writeMillePedeVariables(theAlignables, outFile.c_str(), loop, false, ioerr);
696  if (ioerr) {
697  edm::LogError("Alignment") << "@SUB=MillePedeAlignmentAlgorithm::doIO"
698  << "Problem " << ioerr << " writing MillePedeVariables";
699  ++result;
700  }
701 
702  aliIO.writeOrigRigidBodyAlignmentParameters(theAlignables, outFile.c_str(), loop, false, ioerr);
703  if (ioerr) {
704  edm::LogError("Alignment") << "@SUB=MillePedeAlignmentAlgorithm::doIO" << "Problem " << ioerr
705  << " in writeOrigRigidBodyAlignmentParameters, " << loop;
706  ++result;
707  }
708  aliIO.writeAlignableAbsolutePositions(theAlignables, outFile.c_str(), loop, false, ioerr);
709  if (ioerr) {
710  edm::LogError("Alignment") << "@SUB=MillePedeAlignmentAlgorithm::doIO" << "Problem " << ioerr
711  << " in writeAlignableAbsolutePositions, " << loop;
712  ++result;
713  }
714 
715  return result;
716 }
717 
718 //__________________________________________________________________________________________________
719 void MillePedeAlignmentAlgorithm::buildUserVariables(const std::vector<Alignable*> &alis) const
720 {
721  for (std::vector<Alignable*>::const_iterator iAli = alis.begin(); iAli != alis.end(); ++iAli) {
722  AlignmentParameters *params = (*iAli)->alignmentParameters();
723  if (!params) {
724  throw cms::Exception("Alignment") << "@SUB=MillePedeAlignmentAlgorithm::buildUserVariables"
725  << "No parameters for alignable";
726  }
727  MillePedeVariables *userVars = dynamic_cast<MillePedeVariables*>(params->userVariables());
728  if (userVars) { // Just re-use existing, keeping label and numHits:
729  for (unsigned int iPar = 0; iPar < userVars->size(); ++iPar) {
730  // if (params->hierarchyLevel() > 0) {
731  //std::cout << params->hierarchyLevel() << "\nBefore: " << userVars->parameter()[iPar];
732  // }
733  userVars->setAllDefault(iPar);
734  //std::cout << "\nAfter: " << userVars->parameter()[iPar] << std::endl;
735  }
736  } else { // Nothing yet or erase wrong type:
737  userVars = new MillePedeVariables(params->size(), thePedeLabels->alignableLabel(*iAli));
738  params->setUserVariables(userVars);
739  }
740  }
741 }
742 
743 //__________________________________________________________________________________________________
745 {
746  if (mode == "full") {
748  } else if (mode == "mille") {
749  return myMilleBit; // + myPedeSteerBit; // sic! Including production of steerig file. NO!
750  } else if (mode == "pede") {
752  } else if (mode == "pedeSteer") {
753  return myPedeSteerBit;
754  } else if (mode == "pedeRun") {
755  return myPedeSteerBit + myPedeRunBit + myPedeReadBit; // sic! Including steering and reading of result.
756  } else if (mode == "pedeRead") {
757  return myPedeReadBit;
758  }
759 
760  throw cms::Exception("BadConfig")
761  << "Unknown mode '" << mode
762  << "', use 'full', 'mille', 'pede', 'pedeRun', 'pedeSteer' or 'pedeRead'.";
763 
764  return 0;
765 }
766 
767 //__________________________________________________________________________________________________
769  const std::vector<std::string> &inFiles) const
770 {
771  bool allOk = true;
772  int ierr = 0;
773  MillePedeVariablesIORoot millePedeIO;
774  for (std::vector<std::string>::const_iterator iFile = inFiles.begin();
775  iFile != inFiles.end(); ++iFile) {
776  const std::string inFile(theDir + *iFile);
777  const std::vector<AlignmentUserVariables*> mpVars =
778  millePedeIO.readMillePedeVariables(theAlignables, inFile.c_str(), fromIov, ierr);
779  if (ierr || !this->addHits(theAlignables, mpVars)) {
780  edm::LogError("Alignment") << "@SUB=MillePedeAlignmentAlgorithm::addHitStatistics"
781  << "Error " << ierr << " reading from " << inFile
782  << ", tree " << fromIov << ", or problems in addHits";
783  allOk = false;
784  }
785  for (std::vector<AlignmentUserVariables*>::const_iterator i = mpVars.begin();
786  i != mpVars.end(); ++i) {
787  delete *i; // clean created objects
788  }
789  }
790 
791  return allOk;
792 }
793 
794 //__________________________________________________________________________________________________
795 bool MillePedeAlignmentAlgorithm::addHits(const std::vector<Alignable*> &alis,
796  const std::vector<AlignmentUserVariables*> &mpVars) const
797 {
798  bool allOk = (mpVars.size() == alis.size());
799  std::vector<AlignmentUserVariables*>::const_iterator iUser = mpVars.begin();
800  for (std::vector<Alignable*>::const_iterator iAli = alis.begin();
801  iAli != alis.end() && iUser != mpVars.end(); ++iAli, ++iUser) {
802  MillePedeVariables *mpVarNew = dynamic_cast<MillePedeVariables*>(*iUser);
803  AlignmentParameters *ps = (*iAli)->alignmentParameters();
804  MillePedeVariables *mpVarOld = (ps ? dynamic_cast<MillePedeVariables*>(ps->userVariables()) : 0);
805  if (!mpVarNew || !mpVarOld || mpVarOld->size() != mpVarNew->size()) {
806  allOk = false;
807  continue; // FIXME error etc.?
808  }
809 
810  mpVarOld->increaseHitsX(mpVarNew->hitsX());
811  mpVarOld->increaseHitsY(mpVarNew->hitsY());
812  }
813 
814  return allOk;
815 }
816 
817 //__________________________________________________________________________________________________
818 void MillePedeAlignmentAlgorithm::makeGlobDerivMatrix(const std::vector<float> &globalDerivativesx,
819  const std::vector<float> &globalDerivativesy,
820  TMatrixF &aGlobalDerivativesM)
821 {
822 
823  for (unsigned int i = 0; i < globalDerivativesx.size(); ++i) {
824  aGlobalDerivativesM(0,i) = globalDerivativesx[i];
825  aGlobalDerivativesM(1,i) = globalDerivativesy[i];
826  }
827 }
828 
829 //__________________________________________________________________________________________________
831 (TMatrixDSym &aHitCovarianceM, TMatrixF &aLocalDerivativesM, TMatrixF &aHitResidualsM,
832  TMatrixF &aGlobalDerivativesM) const
833 {
834  TMatrixDSymEigen myDiag(aHitCovarianceM);
835  TMatrixD aTranfoToDiagonalSystem = myDiag.GetEigenVectors();
836  TMatrixD aTranfoToDiagonalSystemInv = myDiag.GetEigenVectors( );
837  TMatrixF aTranfoToDiagonalSystemInvF = myDiag.GetEigenVectors( );
838  TMatrixD aMatrix = aTranfoToDiagonalSystemInv.Invert() * aHitCovarianceM * aTranfoToDiagonalSystem;
839  // Tranformation of matrix M is done by A^T*M*A, not A^{-1}*M*A.
840  // But here A^T == A^{-1}, so we would only save CPU by Transpose()...
841  // FIXME this - I guess simply use T(), not Transpose()...
842  // TMatrixD aMatrix = aTranfoToDiagonalSystemInv.Transpose() * aHitCovarianceM
843  // * aTranfoToDiagonalSystem;
844  aHitCovarianceM = TMatrixDSym(2, aMatrix.GetMatrixArray());
845  aTranfoToDiagonalSystemInvF.Invert();
846  //edm::LogInfo("Alignment") << "NEW HIT loca in matrix"<<aLocalDerivativesM(0,0);
847  aLocalDerivativesM = aTranfoToDiagonalSystemInvF * aLocalDerivativesM;
848 
849  //edm::LogInfo("Alignment") << "NEW HIT loca in matrix after diag:"<<aLocalDerivativesM(0,0);
850  aHitResidualsM = aTranfoToDiagonalSystemInvF * aHitResidualsM;
851  aGlobalDerivativesM = aTranfoToDiagonalSystemInvF * aGlobalDerivativesM;
852 }
853 
854 //__________________________________________________________________________________________________
857  unsigned int iVirtualMeas, TMatrixDSym &aHitCovarianceM,
858  TMatrixF &aHitResidualsM, TMatrixF &aLocalDerivativesM)
859 {
860  // This Method is valid for 1D measurements only
861 
862  const unsigned int xIndex = iVirtualMeas + refTrajPtr->numberOfHitMeas();
863  // Covariance into a TMatrixDSym
864 
865  //aHitCovarianceM = new TMatrixDSym(1);
866  aHitCovarianceM(0,0)=refTrajPtr->measurementErrors()[xIndex][xIndex];
867 
868  //theHitResidualsM= new TMatrixF(1,1);
869  aHitResidualsM(0,0)= refTrajPtr->measurements()[xIndex];
870 
871  // Local Derivatives into a TMatrixDSym (to use matrix operations)
872  const AlgebraicMatrix &locDerivMatrix = refTrajPtr->derivatives();
873  // theLocalDerivativeNumber = locDerivMatrix.num_col();
874 
875  //theLocalDerivativesM = new TMatrixF(1,locDerivMatrix.num_col());
876  for (int i = 0; i < locDerivMatrix.num_col(); ++i) {
877  aLocalDerivativesM(0,i) = locDerivMatrix[xIndex][i];
878  }
879 }
880 
881 //__________________________________________________________________________________________________
884  unsigned int iTrajHit, TMatrixDSym &aHitCovarianceM,
885  TMatrixF &aHitResidualsM, TMatrixF &aLocalDerivativesM)
886 {
887  // This Method is valid for 2D measurements only
888 
889  const unsigned int xIndex = iTrajHit*2;
890  const unsigned int yIndex = iTrajHit*2+1;
891  // Covariance into a TMatrixDSym
892 
893  //aHitCovarianceM = new TMatrixDSym(2);
894  aHitCovarianceM(0,0)=refTrajPtr->measurementErrors()[xIndex][xIndex];
895  aHitCovarianceM(0,1)=refTrajPtr->measurementErrors()[xIndex][yIndex];
896  aHitCovarianceM(1,0)=refTrajPtr->measurementErrors()[yIndex][xIndex];
897  aHitCovarianceM(1,1)=refTrajPtr->measurementErrors()[yIndex][yIndex];
898 
899  //theHitResidualsM= new TMatrixF(2,1);
900  aHitResidualsM(0,0)= refTrajPtr->measurements()[xIndex] - refTrajPtr->trajectoryPositions()[xIndex];
901  aHitResidualsM(1,0)= refTrajPtr->measurements()[yIndex] - refTrajPtr->trajectoryPositions()[yIndex];
902 
903  // Local Derivatives into a TMatrixDSym (to use matrix operations)
904  const AlgebraicMatrix &locDerivMatrix = refTrajPtr->derivatives();
905  // theLocalDerivativeNumber = locDerivMatrix.num_col();
906 
907  //theLocalDerivativesM = new TMatrixF(2,locDerivMatrix.num_col());
908  for (int i = 0; i < locDerivMatrix.num_col(); ++i) {
909  aLocalDerivativesM(0,i) = locDerivMatrix[xIndex][i];
910  aLocalDerivativesM(1,i) = locDerivMatrix[yIndex][i];
911  }
912 }
913 
914 //__________________________________________________________________________________________________
917  unsigned int iTrajHit, const std::vector<int> &globalLabels,
918  const std::vector<float> &globalDerivativesX,
919  const std::vector<float> &globalDerivativesY)
920 {
921  const ConstRecHitPointer aRecHit(refTrajPtr->recHits()[iTrajHit]);
922 
923  if((aRecHit)->dimension() == 1) {
924  return this->callMille1D(refTrajPtr, iTrajHit, globalLabels, globalDerivativesX);
925  } else {
926  return this->callMille2D(refTrajPtr, iTrajHit, globalLabels,
927  globalDerivativesX, globalDerivativesY);
928  }
929 }
930 
931 
932 //__________________________________________________________________________________________________
935  unsigned int iTrajHit, const std::vector<int> &globalLabels,
936  const std::vector<float> &globalDerivativesX)
937 {
938  const ConstRecHitPointer aRecHit(refTrajPtr->recHits()[iTrajHit]);
939  const unsigned int xIndex = iTrajHit*2; // the even ones are local x
940 
941  // local derivatives
942  const AlgebraicMatrix &locDerivMatrix = refTrajPtr->derivatives();
943  const int nLocal = locDerivMatrix.num_col();
944  std::vector<float> localDerivatives(nLocal);
945  for (unsigned int i = 0; i < localDerivatives.size(); ++i) {
946  localDerivatives[i] = locDerivMatrix[xIndex][i];
947  }
948 
949  // residuum and error
950  float residX = refTrajPtr->measurements()[xIndex] - refTrajPtr->trajectoryPositions()[xIndex];
951  float hitErrX = TMath::Sqrt(refTrajPtr->measurementErrors()[xIndex][xIndex]);
952 
953  // number of global derivatives
954  const int nGlobal = globalDerivativesX.size();
955 
956  // &(localDerivatives[0]) etc. are valid - as long as vector is not empty
957  // cf. http://www.parashift.com/c++-faq-lite/containers.html#faq-34.3
958  theMille->mille(nLocal, &(localDerivatives[0]), nGlobal, &(globalDerivativesX[0]),
959  &(globalLabels[0]), residX, hitErrX);
960 
961  if (theMonitor) {
962  theMonitor->fillDerivatives(aRecHit, &(localDerivatives[0]), nLocal,
963  &(globalDerivativesX[0]), nGlobal, &(globalLabels[0]));
964  theMonitor->fillResiduals(aRecHit, refTrajPtr->trajectoryStates()[iTrajHit],
965  iTrajHit, residX, hitErrX, false);
966  }
967 
968  return 1;
969 }
970 
971 //__________________________________________________________________________________________________
974  unsigned int iTrajHit, const std::vector<int> &globalLabels,
975  const std::vector<float> &globalDerivativesx,
976  const std::vector<float> &globalDerivativesy)
977 {
978  const ConstRecHitPointer aRecHit(refTrajPtr->recHits()[iTrajHit]);
979 
980  if((aRecHit)->dimension() != 2) {
981  edm::LogError("Alignment") << "@SUB=MillePedeAlignmentAlgorithm::callMille2D"
982  << "You try to call method for 2D hits for a "
983  << (aRecHit)->dimension()
984  << "D Hit. Hit gets ignored!";
985  return -1;
986  }
987 
988  TMatrixDSym aHitCovarianceM(2);
989  TMatrixF aHitResidualsM(2,1);
990  TMatrixF aLocalDerivativesM(2, refTrajPtr->derivatives().num_col());
991  // below method fills above 3 matrices
992  this->addRefTrackData2D(refTrajPtr, iTrajHit, aHitCovarianceM,aHitResidualsM,aLocalDerivativesM);
993  TMatrixF aGlobalDerivativesM(2,globalDerivativesx.size());
994  this->makeGlobDerivMatrix(globalDerivativesx, globalDerivativesy, aGlobalDerivativesM);
995 
996  // calculates correlation between Hit measurements
997  // FIXME: Should take correlation (and resulting transformation) from original hit,
998  // not 2x2 matrix from ReferenceTrajectory: That can come from error propagation etc.!
999  const double corr = aHitCovarianceM(0,1) / sqrt(aHitCovarianceM(0,0) * aHitCovarianceM(1,1));
1000  if (theMonitor) theMonitor->fillCorrelations2D(corr, aRecHit);
1001  bool diag = false; // diagonalise only tracker TID, TEC
1002  switch(aRecHit->geographicalId().subdetId()) {
1003  case SiStripDetId::TID:
1004  case SiStripDetId::TEC:
1005  if (aRecHit->geographicalId().det() == DetId::Tracker && TMath::Abs(corr) > theMaximalCor2D) {
1006  this->diagonalize(aHitCovarianceM, aLocalDerivativesM, aHitResidualsM, aGlobalDerivativesM);
1007  diag = true;
1008  }
1009  break;
1010  default:;
1011  }
1012 
1013  float newResidX = aHitResidualsM(0,0);
1014  float newResidY = aHitResidualsM(1,0);
1015  float newHitErrX = TMath::Sqrt(aHitCovarianceM(0,0));
1016  float newHitErrY = TMath::Sqrt(aHitCovarianceM(1,1));
1017  float *newLocalDerivsX = aLocalDerivativesM[0].GetPtr();
1018  float *newLocalDerivsY = aLocalDerivativesM[1].GetPtr();
1019  float *newGlobDerivsX = aGlobalDerivativesM[0].GetPtr();
1020  float *newGlobDerivsY = aGlobalDerivativesM[1].GetPtr();
1021  const int nLocal = aLocalDerivativesM.GetNcols();
1022  const int nGlobal = aGlobalDerivativesM.GetNcols();
1023 
1024  if (diag && (newHitErrX > newHitErrY)) { // also for 2D hits?
1025  // measurement with smaller error is x-measurement (for !is2D do not fill y-measurement):
1026  std::swap(newResidX, newResidY);
1027  std::swap(newHitErrX, newHitErrY);
1028  std::swap(newLocalDerivsX, newLocalDerivsY);
1029  std::swap(newGlobDerivsX, newGlobDerivsY);
1030  }
1031 
1032  // &(globalLabels[0]) is valid - as long as vector is not empty
1033  // cf. http://www.parashift.com/c++-faq-lite/containers.html#faq-34.3
1034  theMille->mille(nLocal, newLocalDerivsX, nGlobal, newGlobDerivsX,
1035  &(globalLabels[0]), newResidX, newHitErrX);
1036 
1037  if (theMonitor) {
1038  theMonitor->fillDerivatives(aRecHit, newLocalDerivsX, nLocal, newGlobDerivsX, nGlobal,
1039  &(globalLabels[0]));
1040  theMonitor->fillResiduals(aRecHit, refTrajPtr->trajectoryStates()[iTrajHit],
1041  iTrajHit, newResidX, newHitErrX, false);
1042  }
1043  const bool isReal2DHit = this->is2D(aRecHit); // strip is 1D (except matched hits)
1044  if (isReal2DHit) {
1045  theMille->mille(nLocal, newLocalDerivsY, nGlobal, newGlobDerivsY,
1046  &(globalLabels[0]), newResidY, newHitErrY);
1047  if (theMonitor) {
1048  theMonitor->fillDerivatives(aRecHit, newLocalDerivsY, nLocal, newGlobDerivsY, nGlobal,
1049  &(globalLabels[0]));
1050  theMonitor->fillResiduals(aRecHit, refTrajPtr->trajectoryStates()[iTrajHit],
1051  iTrajHit, newResidY, newHitErrY, true);// true: y
1052  }
1053  }
1054 
1055  return (isReal2DHit ? 2 : 1);
1056 }
1057 
1058 //__________________________________________________________________________________________________
1060 ::addVirtualMeas(const ReferenceTrajectoryBase::ReferenceTrajectoryPtr &refTrajPtr, unsigned int iVirtualMeas)
1061 {
1062  TMatrixDSym aHitCovarianceM(1);
1063  TMatrixF aHitResidualsM(1,1);
1064  TMatrixF aLocalDerivativesM(1, refTrajPtr->derivatives().num_col());
1065  // below method fills above 3 'matrices'
1066  this->addRefTrackVirtualMeas1D(refTrajPtr, iVirtualMeas, aHitCovarianceM, aHitResidualsM, aLocalDerivativesM);
1067 
1068  // no global parameters (use dummy 0)
1069  TMatrixF aGlobalDerivativesM(1,1);
1070  aGlobalDerivativesM(0,0) = 0;
1071 
1072  float newResidX = aHitResidualsM(0,0);
1073  float newHitErrX = TMath::Sqrt(aHitCovarianceM(0,0));
1074  float *newLocalDerivsX = aLocalDerivativesM[0].GetPtr();
1075  float *newGlobDerivsX = aGlobalDerivativesM[0].GetPtr();
1076  const int nLocal = aLocalDerivativesM.GetNcols();
1077  const int nGlobal = 0;
1078 
1079  theMille->mille(nLocal, newLocalDerivsX, nGlobal, newGlobDerivsX,
1080  &nGlobal, newResidX, newHitErrX);
1081 }
1082 
1083 //____________________________________________________
1085  const TkFittedLasBeamCollection &lasBeams,
1086  const TsosVectorCollection &lasBeamTsoses)
1087 {
1088  TsosVectorCollection::const_iterator iTsoses = lasBeamTsoses.begin();
1089  for(TkFittedLasBeamCollection::const_iterator iBeam = lasBeams.begin(), iEnd = lasBeams.end();
1090  iBeam != iEnd; ++iBeam, ++iTsoses){ // beam/tsoses parallel!
1091 
1092  edm::LogInfo("Alignment") << "@SUB=MillePedeAlignmentAlgorithm::addLaserData"
1093  << "Beam " << iBeam->getBeamId() << " with "
1094  << iBeam->parameters().size() << " parameters and "
1095  << iBeam->getData().size() << " hits.\n There are "
1096  << iTsoses->size() << " TSOSes.";
1097 
1098  this->addLasBeam(eventInfo, *iBeam, *iTsoses);
1099  }
1100 }
1101 
1102 //____________________________________________________
1104  const TkFittedLasBeam &lasBeam,
1105  const std::vector<TrajectoryStateOnSurface> &tsoses)
1106 {
1107  AlignmentParameters *dummyPtr = 0; // for globalDerivativesHierarchy()
1108  std::vector<float> lasLocalDerivsX; // buffer for local derivatives
1109  const unsigned int beamLabel = thePedeLabels->lasBeamLabel(lasBeam.getBeamId());// for global par
1110 
1111  for (unsigned int iHit = 0; iHit < tsoses.size(); ++iHit) {
1112  if (!tsoses[iHit].isValid()) continue;
1113  // clear buffer
1114  theFloatBufferX.clear();
1115  theFloatBufferY.clear();
1116  theIntBuffer.clear();
1117  lasLocalDerivsX.clear();
1118  // get alignables and global parameters
1119  const SiStripLaserRecHit2D &hit = lasBeam.getData()[iHit];
1121  this->globalDerivativesHierarchy(eventInfo,
1122  tsoses[iHit], lasAli, lasAli,
1124  // fill derivatives vector from derivatives matrix
1125  for (unsigned int nFitParams = 0;
1126  nFitParams < static_cast<unsigned int>(lasBeam.parameters().size());
1127  ++nFitParams) {
1128  const float derivative = lasBeam.derivatives()[iHit][nFitParams];
1129  if (nFitParams < lasBeam.firstFixedParameter()) { // first local beam parameters
1130  lasLocalDerivsX.push_back(derivative);
1131  } else { // now global ones
1132  const unsigned int numPar = nFitParams - lasBeam.firstFixedParameter();
1133  theIntBuffer.push_back(thePedeLabels->parameterLabel(beamLabel, numPar));
1134  theFloatBufferX.push_back(derivative);
1135  }
1136  } // end loop over parameters
1137 
1138  const float residual = hit.localPosition().x() - tsoses[iHit].localPosition().x();
1139  // error from file or assume 0.003
1140  const float error = 0.003; // hit.localPositionError().xx(); sqrt???
1141 
1142  theMille->mille(lasLocalDerivsX.size(), &(lasLocalDerivsX[0]), theFloatBufferX.size(),
1143  &(theFloatBufferX[0]), &(theIntBuffer[0]), residual, error);
1144  } // end of loop over hits
1145 
1146  theMille->end();
1147 }
1148 
1150 {
1151  // do some printing, if requested
1152  const bool doOutputOnStdout(pxbSurveyCfg.getParameter<bool>("doOutputOnStdout"));
1153  if (doOutputOnStdout) std::cout << "# Output from addPxbSurvey follows below because doOutputOnStdout is set to True" << std::endl;
1154 
1155  // instantiate a dicer object
1156  SurveyPxbDicer dicer(pxbSurveyCfg.getParameter<std::vector<edm::ParameterSet> >("toySurveyParameters"), pxbSurveyCfg.getParameter<unsigned int>("toySurveySeed"));
1157  std::ofstream outfile(pxbSurveyCfg.getUntrackedParameter<std::string>("toySurveyFile").c_str());
1158 
1159  // read data from file
1160  std::vector<SurveyPxbImageLocalFit> measurements;
1161  std::string filename(pxbSurveyCfg.getParameter<edm::FileInPath>("infile").fullPath());
1163 
1164  // loop over photographs (=measurements) and perform the fit
1165  for(std::vector<SurveyPxbImageLocalFit>::size_type i=0; i!=measurements.size(); i++)
1166  {
1167  if (doOutputOnStdout) std::cout << "Module " << i << ": ";
1168 
1169  // get the Alignables and their surfaces
1170  AlignableDetOrUnitPtr mod1(theAlignableNavigator->alignableFromDetId(measurements[i].getIdFirst()));
1171  AlignableDetOrUnitPtr mod2(theAlignableNavigator->alignableFromDetId(measurements[i].getIdSecond()));
1172  const AlignableSurface& surf1 = mod1->surface();
1173  const AlignableSurface& surf2 = mod2->surface();
1174 
1175  // the position of the fiducial points in local frame of a PXB module
1176  const LocalPoint fidpoint0(-0.91,+3.30);
1177  const LocalPoint fidpoint1(+0.91,+3.30);
1178  const LocalPoint fidpoint2(+0.91,-3.30);
1179  const LocalPoint fidpoint3(-0.91,-3.30);
1180 
1181  // We choose the local frame of the first module as reference,
1182  // so take the fidpoints of the second module and calculate their
1183  // positions in the reference frame
1184  const GlobalPoint surf2point0(surf2.toGlobal(fidpoint0));
1185  const GlobalPoint surf2point1(surf2.toGlobal(fidpoint1));
1186  const LocalPoint fidpoint0inSurf1frame(surf1.toLocal(surf2point0));
1187  const LocalPoint fidpoint1inSurf1frame(surf1.toLocal(surf2point1));
1188 
1189  // Create the vector for the fit
1191  fidpointvec.push_back(fidpoint0inSurf1frame);
1192  fidpointvec.push_back(fidpoint1inSurf1frame);
1193  fidpointvec.push_back(fidpoint2);
1194  fidpointvec.push_back(fidpoint3);
1195 
1196  // if toy survey is requested, dice the values now
1197  if (pxbSurveyCfg.getParameter<bool>("doToySurvey"))
1198  {
1199  dicer.doDice(fidpointvec,measurements[i].getIdPair(), outfile);
1200  }
1201 
1202  // do the fit
1203  measurements[i].doFit(fidpointvec, thePedeLabels->alignableLabel(mod1), thePedeLabels->alignableLabel(mod2));
1204  SurveyPxbImageLocalFit::localpars_t a; // local pars from fit
1205  a = measurements[i].getLocalParameters();
1206  const SurveyPxbImageLocalFit::value_t chi2 = measurements[i].getChi2();
1207 
1208  // do some reporting, if requested
1209  if (doOutputOnStdout)
1210  {
1211  std::cout << "a: " << a[0] << ", " << a[1] << ", " << a[2] << ", " << a[3]
1212  << " S= " << sqrt(a[2]*a[2]+a[3]*a[3])
1213  << " phi= " << atan(a[3]/a[2])
1214  << " chi2= " << chi2 << std::endl;
1215  }
1216  if (theMonitor)
1217  {
1219  theMonitor->fillPxbSurveyHistsLocalPars(a[0],a[1],sqrt(a[2]*a[2]+a[3]*a[3]),atan(a[3]/a[2]));
1220  }
1221 
1222  // pass the results from the local fit to mille
1224  {
1225  theMille->mille((int)measurements[i].getLocalDerivsSize(),
1226  measurements[i].getLocalDerivsPtr(j),
1227  (int)measurements[i].getGlobalDerivsSize(),
1228  measurements[i].getGlobalDerivsPtr(j),
1229  measurements[i].getGlobalDerivsLabelPtr(j),
1230  measurements[i].getResiduum(j),
1231  measurements[i].getSigma(j));
1232  }
1233  theMille->end();
1234  }
1235  outfile.close();
1236 }
1237 
unsigned int hitsX() const
get number of hits for x-measurement
const TimeTypeSpecs timeTypeSpecs[]
Definition: Time.cc:22
T getParameter(std::string const &) const
unsigned int firstFixedParameter() const
void globalDerivativesCalibration(const TransientTrackingRecHit::ConstRecHitPointer &recHit, const TrajectoryStateOnSurface &tsos, const edm::EventSetup &setup, const EventInfo &eventInfo, std::vector< float > &globalDerivativesX, std::vector< float > &globalDerivativesY, std::vector< int > &globalLabels) const
adding derivatives from integrated calibrations
T getUntrackedParameter(std::string const &, T const &) const
std::vector< AlignmentUserVariables * > readMillePedeVariables(const std::vector< Alignable * > &alivec, const char *filename, int iter, int &ierr)
int i
Definition: DBlmapReader.cc:9
unsigned int size() const
number of parameters
void resetParameters(void)
reset parameters, correlations, user variables
void increaseHitsX(unsigned int add=1)
increase hits for x-measurement
bool read(std::vector< Alignable * > &alignables, bool setUserVars)
Definition: PedeReader.cc:52
std::vector< coord_t > fidpoint_t
void increaseHitsY(unsigned int add=1)
increase hits for y-measurement
std::vector< Alignable * > theAlignables
TrajectoryFactoryBase::ReferenceTrajectoryCollection RefTrajColl
std::vector< ParameterSet > VParameterSet
Definition: ParameterSet.h:33
virtual unsigned int alignableLabel(Alignable *alignable) const =0
void writeAlignableOriginalPositions(const align::Alignables &alivec, const char *filename, int iter, bool validCheck, int &ierr)
write Alignable original (before misalignment) absolute positions
void fillPxbSurveyHistsLocalPars(const float &a0, const float &a1, const float &S, const float &phi)
bool exists(std::string const &parameterName) const
checks if a parameter exists
bool globalDerivativesHierarchy(const EventInfo &eventInfo, const TrajectoryStateOnSurface &tsos, Alignable *ali, const AlignableDetOrUnitPtr &alidet, std::vector< float > &globalDerivativesX, std::vector< float > &globalDerivativesY, std::vector< int > &globalLabels, AlignmentParameters *&lowestParams) const
recursively adding derivatives and labels, false if problems
void restoreCachedTransformations(void)
restore the previously cached position, rotation and other parameters
void applyParameters(void)
Obsolete: Use AlignableNavigator::alignableDetFromDetId and alignableFromAlignableDet.
unsigned int addHitCount(const std::vector< AlignmentParameters * > &parVec, const std::vector< bool > &validHitVecY) const
virtual LocalPoint localPosition() const
const AlgebraicMatrix & derivatives() const
matrix of local derivatives: columns are parameters, rows are hits
const std::vector< bool > & selector(void) const
Get alignment parameter selector vector.
int callMille2D(const ReferenceTrajectoryBase::ReferenceTrajectoryPtr &refTrajPtr, unsigned int iTrajHit, const std::vector< int > &globalLabels, const std::vector< float > &globalDerivativesx, const std::vector< float > &globalDerivativesy)
std::pair< RunNumber, RunNumber > RunRange
const ConstTrajTrackPairCollection & trajTrackPairs_
const TsosVectorCollection * tkLasBeamTsoses_
might be null!
virtual unsigned int lasBeamLabel(unsigned int lasBeamId) const =0
virtual void initialize(const edm::EventSetup &setup, AlignableTracker *tracker, AlignableMuon *muon, AlignableExtras *extras, AlignmentParameterStore *store)
Call at beginning of job.
uint16_t size_type
void addLasBeam(const EventInfo &eventInfo, const TkFittedLasBeam &lasBeam, const std::vector< TrajectoryStateOnSurface > &tsoses)
AlignmentParameters * alignmentParameters() const
Get the AlignmentParameters.
Definition: Alignable.h:57
void fillPxbSurveyHistsChi2(const float &chi2)
virtual unsigned int parameterLabel(unsigned int aliLabel, unsigned int parNum) const =0
returns the label for a given alignable parameter number combination
unsigned int doIO(int loop) const
int callMille(const ReferenceTrajectoryBase::ReferenceTrajectoryPtr &refTrajPtr, unsigned int iTrajHit, const std::vector< int > &globalLabels, const std::vector< float > &globalDerivativesX, const std::vector< float > &globalDerivativesY)
calls callMille1D or callMille2D
TransientTrackingRecHit::ConstRecHitPointer ConstRecHitPointer
const AlgebraicVector & parameters(void) const
Get alignment parameters.
std::string doDice(const fidpoint_t &fidpointvec, const idPair_t &id, const bool rotate=false)
AlignmentUserVariables * userVariables(void) const
Get pointer to user variables.
int callMille1D(const ReferenceTrajectoryBase::ReferenceTrajectoryPtr &refTrajPtr, unsigned int iTrajHit, const std::vector< int > &globalLabels, const std::vector< float > &globalDerivativesX)
calls Mille for 1D hits
void addLaserData(const EventInfo &eventInfo, const TkFittedLasBeamCollection &tkLasBeams, const TsosVectorCollection &tkLasBeamTsoses)
int addMeasurementData(const edm::EventSetup &setup, const EventInfo &eventInfo, const ReferenceTrajectoryBase::ReferenceTrajectoryPtr &refTrajPtr, unsigned int iHit, AlignmentParameters *&params)
list outfile
Definition: EdgesToViz.py:91
virtual void terminate(const edm::EventSetup &iSetup)
Call at end of job.
bool isMode(unsigned int testMode) const
align::RotationType toLocal(const align::RotationType &) const
Return in local frame a rotation given in global frame.
virtual AlgebraicMatrix derivatives(const TrajectoryStateOnSurface &tsos, const AlignableDetOrUnitPtr &alidet) const =0
Get derivatives of selected parameters.
CLHEP::HepMatrix AlgebraicMatrix
const std::vector< Scalar > & parameters() const
parallel to derivatives()
void fillUsedTrack(const reco::Track *track, unsigned int nHitX, unsigned int nHitY)
virtual bool setParametersForRunRange(const RunRange &runrange)
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
T sqrt(T t)
Definition: SSEVec.h:48
virtual void endRun(const EventInfo &eventInfo, const EndRunInfo &runInfo, const edm::EventSetup &setup)
Run on run products, e.g. TkLAS.
int runPede(const std::string &masterSteer) const
run pede, masterSteer should be as returned from buildMasterSteer(...)
Definition: PedeSteerer.cc:790
unsigned int getBeamId(void) const
return the full beam identifier
Definition: TkLasBeam.h:25
void end()
Definition: Mille.cc:129
tuple result
Definition: query.py:137
AlignmentParameterStore * theAlignmentParameterStore
directory for all kind of files
unsigned int hitsY() const
get number of hits for y-measurement
bool is2D(const TransientTrackingRecHit::ConstRecHitPointer &recHit) const
true if hit belongs to 2D detector (currently tracker specific)
void diagonalize(TMatrixDSym &aHitCovarianceM, TMatrixF &aLocalDerivativesM, TMatrixF &aHitResidualsM, TMatrixF &theGlobalDerivativesM) const
int j
Definition: DBlmapReader.cc:9
std::string buildMasterSteer(const std::vector< std::string > &binaryFiles)
construct (and return name of) master steering file from config, binaryFiles etc. ...
Definition: PedeSteerer.cc:750
Container::value_type value_type
void mille(int NLC, const float *derLc, int NGL, const float *derGl, const int *label, float rMeas, float sigma)
Definition: Mille.cc:43
const AlignableSurface & surface() const
Return the Surface (global position and orientation) of the object.
Definition: Alignable.h:126
bool addHits(const std::vector< Alignable * > &alis, const std::vector< AlignmentUserVariables * > &mpVars) const
void writeMillePedeVariables(const std::vector< Alignable * > &alivec, const char *filename, int iter, bool validCheck, int &ierr)
bool addHitStatistics(int fromLoop, const std::string &outFile, const std::vector< std::string > &inFiles) const
tuple out
Definition: dbtoconf.py:99
std::vector< ConstRecHitPointer > ConstRecHitContainer
bool areEmptyParams(const std::vector< Alignable * > &alignables) const
void addVirtualMeas(const ReferenceTrajectoryBase::ReferenceTrajectoryPtr &refTrajPtr, unsigned int iVirtualMeas)
adds data for virtual measurements from reference trajectory
bool readFromPede(const edm::ParameterSet &mprespset, bool setUserVars, const RunRange &runrange)
read pede input defined by &#39;psetName&#39;, flag to create/not create MillePedeVariables ...
CLHEP::HepVector AlgebraicVector
std::pair< unsigned int, unsigned int > addReferenceTrajectory(const edm::EventSetup &setup, const EventInfo &eventInfo, const ReferenceTrajectoryBase::ReferenceTrajectoryPtr &refTrajPtr)
fill mille for a trajectory, returning number of x/y hits ([0,0] if &#39;bad&#39; trajectory) ...
std::vector< ReferenceTrajectoryPtr > ReferenceTrajectoryCollection
const SiStripDetId & getDetId(void) const
void addRefTrackData2D(const ReferenceTrajectoryBase::ReferenceTrajectoryPtr &refTrajPtr, unsigned int iTrajHit, TMatrixDSym &aHitCovarianceM, TMatrixF &aHitResidualsM, TMatrixF &aLocalDerivativesM)
adds data from reference trajectory from a specific Hit
void setUserVariables(AlignmentUserVariables *auv)
Set pointer to user variables.
std::vector< IntegratedCalibrationBase * > theCalibrations
int size(void) const
Get number of parameters.
void buildSubSteer(AlignableTracker *aliTracker, AlignableMuon *aliMuon, AlignableExtras *aliExtras)
construct steering files about hierarchy, fixing etc. an keep track of their names ...
Definition: PedeSteerer.cc:669
void makeGlobDerivMatrix(const std::vector< float > &globalDerivativesx, const std::vector< float > &globalDerivativesy, TMatrixF &aGlobalDerivativesM)
tuple tracks
Definition: testEve_cfg.py:39
void addUntrackedParameter(std::string const &name, T const &value)
Definition: ParameterSet.h:206
Class to hold one picture of the BPix survey.
const TkFittedLasBeamCollection * tkLasBeams_
const T & get() const
Definition: EventSetup.h:55
T const * product() const
Definition: ESHandle.h:62
std::vector< value_t > localpars_t
void fillTrack(const reco::Track *track)
virtual bool addCalibrations(const std::vector< IntegratedCalibrationBase * > &iCals)
pass integrated calibrations to Millepede (they are not owned by Millepede!)
virtual void run(const edm::EventSetup &setup, const EventInfo &eventInfo)
Run the algorithm on trajectories and tracks.
define run information passed to algorithms (in endRun)
virtual unsigned int calibrationLabel(const IntegratedCalibrationBase *calib, unsigned int paramNum) const
label for parameter &#39;paramNum&#39; (counted from 0) of an integrated calibration
void buildUserVariables(const std::vector< Alignable * > &alignables) const
add MillePedeVariables for each AlignmentParameters (exception if no parameters...)
MillePedeAlignmentAlgorithm(const edm::ParameterSet &cfg)
Constructor.
TrajectoryFactoryBase * theTrajectoryFactory
virtual ~MillePedeAlignmentAlgorithm()
Destructor.
virtual void addCalibrations(const std::vector< IntegratedCalibrationBase * > &iCals)
tell labeler to treat also integrated calibrations
std::vector< TkFittedLasBeam > TkFittedLasBeamCollection
double a
Definition: hdecay.h:121
align::GlobalPoints toGlobal(const align::LocalPoints &) const
Return in global coord given a set of local points.
void cacheTransformations(void)
cache the current position, rotation and other parameters
virtual const ReferenceTrajectoryCollection trajectories(const edm::EventSetup &setup, const ConstTrajTrackPairCollection &tracks, const reco::BeamSpot &beamSpot) const =0
tuple filename
Definition: lut2db_cfg.py:20
void fillRefTrajectory(const ReferenceTrajectoryBase::ReferenceTrajectoryPtr &refTrajPtr)
Definition: Mille.h:26
TransientTrackingRecHit::ConstRecHitContainer ConstRecHitContainer
void kill()
Definition: Mille.cc:121
tuple cout
Definition: gather_cfg.py:121
void addRefTrackVirtualMeas1D(const ReferenceTrajectoryBase::ReferenceTrajectoryPtr &refTrajPtr, unsigned int iVirtualMeas, TMatrixDSym &aHitCovarianceM, TMatrixF &aHitResidualsM, TMatrixF &aLocalDerivativesM)
adds data for a specific virtual measurement from reference trajectory
static const count_t nMsrmts
void writeAlignableAbsolutePositions(const align::Alignables &alivec, const char *filename, int iter, bool validCheck, int &ierr)
write Alignable current absolute positions
void addPxbSurvey(const edm::ParameterSet &pxbSurveyCfg)
add measurement data from PXB survey
unsigned int decodeMode(const std::string &mode) const
std::string fullPath() const
Definition: FileInPath.cc:171
const std::vector< SiStripLaserRecHit2D > & getData(void) const
access the collection of hits
Definition: TkLasBeam.h:28
void writeOrigRigidBodyAlignmentParameters(const align::Alignables &alivec, const char *filename, int iter, bool validCheck, int &ierr)
write RigidBodyAlignmentParameters as applied on top of original positions
std::vector< std::vector< TrajectoryStateOnSurface > > TsosVectorCollection
const AlgebraicSymMatrix & covariance(void) const
Get parameter covariance matrix.
Constructor of the full muon geometry.
Definition: AlignableMuon.h:36
uint32_t dimension(pat::CandKinResolution::Parametrization parametrization)
Returns the number of free parameters in a parametrization (3 or 4)
AlignableDetOrUnitPtr alignableFromDetId(const DetId &detid)
Returns AlignableDetOrUnitPtr corresponding to given DetId.
Alignable * mother() const
Return pointer to container alignable (if any)
Definition: Alignable.h:85
void setup(std::vector< TH2F > &depth, std::string name, std::string units="")
tuple size
Write out results.
T get(const Candidate &c)
Definition: component.h:55
const align::Alignables & alignables(void) const
get all alignables
std::vector< ConstTrajTrackPair > ConstTrajTrackPairCollection
bool setAllDefault(unsigned int nParam)
set default values for all data concerning nParam (false if nParam out of range)
A derivative(const A &_)
Definition: Derivative.h:18
define event information passed to algorithms