00001
00009
00010 #include "Alignment/CommonAlignmentAlgorithm/interface/AlignmentParameterStore.h"
00011
00012 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00013 #include "FWCore/Utilities/interface/Exception.h"
00014 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00015
00016 #include "Alignment/CommonAlignment/interface/Alignable.h"
00017 #include "Alignment/CommonAlignment/interface/AlignableDetOrUnitPtr.h"
00018 #include "Alignment/TrackerAlignment/interface/TrackerAlignableId.h"
00019
00020 #include "Alignment/CommonAlignmentParametrization/interface/RigidBodyAlignmentParameters.h"
00021 #include "Alignment/CommonAlignmentParametrization/interface/ParametersToParametersDerivatives.h"
00022 #include "Alignment/CommonAlignmentAlgorithm/interface/AlignmentExtendedCorrelationsStore.h"
00023 #include "DataFormats/TrackingRecHit/interface/AlignmentPositionError.h"
00024
00025
00026
00027 AlignmentParameterStore::AlignmentParameterStore( const align::Alignables &alis,
00028 const edm::ParameterSet& config ) :
00029 theAlignables(alis)
00030 {
00031 if (config.getUntrackedParameter<bool>("UseExtendedCorrelations")) {
00032 theCorrelationsStore = new AlignmentExtendedCorrelationsStore
00033 (config.getParameter<edm::ParameterSet>("ExtendedCorrelationsConfig"));
00034 } else {
00035 theCorrelationsStore = new AlignmentCorrelationsStore();
00036 }
00037
00038 edm::LogInfo("Alignment") << "@SUB=AlignmentParameterStore"
00039 << "Created with " << theAlignables.size() << " alignables.";
00040 }
00041
00042
00043 AlignmentParameterStore::~AlignmentParameterStore()
00044 {
00045 delete theCorrelationsStore;
00046 }
00047
00048
00049 CompositeAlignmentParameters
00050 AlignmentParameterStore::selectParameters( const std::vector<AlignableDet*>& alignabledets ) const
00051 {
00052 std::vector<AlignableDetOrUnitPtr> detOrUnits;
00053 detOrUnits.reserve(alignabledets.size());
00054
00055 std::vector<AlignableDet*>::const_iterator it, iEnd;
00056 for ( it = alignabledets.begin(), iEnd = alignabledets.end(); it != iEnd; ++it)
00057 detOrUnits.push_back(AlignableDetOrUnitPtr(*it));
00058
00059 return this->selectParameters(detOrUnits);
00060 }
00061
00062
00063 CompositeAlignmentParameters
00064 AlignmentParameterStore::selectParameters( const std::vector<AlignableDetOrUnitPtr>& alignabledets ) const
00065 {
00066
00067 align::Alignables alignables;
00068 std::map <AlignableDetOrUnitPtr,Alignable*> alidettoalimap;
00069 std::map <Alignable*,int> aliposmap;
00070 std::map <Alignable*,int> alilenmap;
00071 int nparam=0;
00072
00073
00074 for( std::vector<AlignableDetOrUnitPtr>::const_iterator iad = alignabledets.begin();
00075 iad != alignabledets.end(); ++iad )
00076 {
00077 Alignable* ali = alignableFromAlignableDet( *iad );
00078 if ( ali )
00079 {
00080 alidettoalimap[ *iad ] = ali;
00081
00082 if ( find(alignables.begin(),alignables.end(),ali) == alignables.end() )
00083 {
00084 alignables.push_back(ali);
00085 AlignmentParameters* ap = ali->alignmentParameters();
00086 nparam += ap->numSelected();
00087 }
00088 }
00089 }
00090
00091 AlgebraicVector* selpar = new AlgebraicVector( nparam, 0 );
00092 AlgebraicSymMatrix* selcov = new AlgebraicSymMatrix( nparam, 0 );
00093
00094
00095 int ipos = 1;
00096 align::Alignables::const_iterator it1;
00097 for( it1 = alignables.begin(); it1 != alignables.end(); ++it1 )
00098 {
00099 AlignmentParameters* ap = (*it1)->alignmentParameters();
00100 selpar->sub( ipos, ap->selectedParameters() );
00101 selcov->sub( ipos, ap->selectedCovariance() );
00102 int npar = ap->numSelected();
00103 aliposmap[*it1]=ipos;
00104 alilenmap[*it1]=npar;
00105 ipos +=npar;
00106 }
00107
00108
00109
00110
00111 ipos = 1;
00112 for( it1 = alignables.begin(); it1 != alignables.end(); ++it1 )
00113 {
00114 int jpos=1;
00115
00116
00117 align::Alignables::const_iterator it2;
00118 for( it2 = alignables.begin(); it2 != it1; ++it2 )
00119 {
00120 theCorrelationsStore->correlations( *it1, *it2, *selcov, ipos-1, jpos-1 );
00121 jpos += (*it2)->alignmentParameters()->numSelected();
00122 }
00123
00124 ipos += (*it1)->alignmentParameters()->numSelected();
00125 }
00126
00127 AlignmentParametersData::DataContainer data( new AlignmentParametersData( selpar, selcov ) );
00128 CompositeAlignmentParameters aap( data, alignables, alidettoalimap, aliposmap, alilenmap );
00129
00130 return aap;
00131 }
00132
00133
00134
00135 CompositeAlignmentParameters
00136 AlignmentParameterStore::selectParameters( const align::Alignables& alignables ) const
00137 {
00138
00139 align::Alignables selectedAlignables;
00140 std::map <AlignableDetOrUnitPtr,Alignable*> alidettoalimap;
00141 std::map <Alignable*,int> aliposmap;
00142 std::map <Alignable*,int> alilenmap;
00143 int nparam=0;
00144
00145
00146 align::Alignables::const_iterator ita;
00147 for ( ita = alignables.begin(); ita != alignables.end(); ++ita )
00148 {
00149
00150 if ( find(selectedAlignables.begin(), selectedAlignables.end(), *ita) == selectedAlignables.end() )
00151 {
00152 selectedAlignables.push_back( *ita );
00153 AlignmentParameters* ap = (*ita)->alignmentParameters();
00154 nparam += ap->numSelected();
00155 }
00156 }
00157
00158 AlgebraicVector* selpar = new AlgebraicVector( nparam, 0 );
00159 AlgebraicSymMatrix* selcov = new AlgebraicSymMatrix( nparam, 0 );
00160
00161
00162 int ipos = 1;
00163 align::Alignables::const_iterator it1;
00164 for( it1 = selectedAlignables.begin(); it1 != selectedAlignables.end(); ++it1 )
00165 {
00166 AlignmentParameters* ap = (*it1)->alignmentParameters();
00167 selpar->sub( ipos, ap->selectedParameters() );
00168 selcov->sub( ipos, ap->selectedCovariance() );
00169 int npar = ap->numSelected();
00170 aliposmap[*it1]=ipos;
00171 alilenmap[*it1]=npar;
00172 ipos +=npar;
00173 }
00174
00175
00176
00177
00178 ipos = 1;
00179 for( it1 = selectedAlignables.begin(); it1 != selectedAlignables.end(); ++it1 )
00180 {
00181 int jpos=1;
00182
00183
00184 align::Alignables::const_iterator it2;
00185 for( it2 = selectedAlignables.begin(); it2 != it1; ++it2 )
00186 {
00187 theCorrelationsStore->correlations( *it1, *it2, *selcov, ipos-1, jpos-1 );
00188 jpos += (*it2)->alignmentParameters()->numSelected();
00189 }
00190
00191 ipos += (*it1)->alignmentParameters()->numSelected();
00192 }
00193
00194 AlignmentParametersData::DataContainer data( new AlignmentParametersData( selpar, selcov ) );
00195 CompositeAlignmentParameters aap( data, selectedAlignables, alidettoalimap, aliposmap, alilenmap );
00196
00197 return aap;
00198 }
00199
00200
00201
00202 void AlignmentParameterStore::updateParameters( const CompositeAlignmentParameters& aap, bool updateCorrelations )
00203 {
00204
00205 align::Alignables alignables = aap.components();
00206 const AlgebraicVector& parameters = aap.parameters();
00207 const AlgebraicSymMatrix& covariance = aap.covariance();
00208
00209 int ipos = 1;
00210
00211
00212 for( align::Alignables::const_iterator it=alignables.begin(); it != alignables.end(); ++it )
00213 {
00214
00215 AlignmentParameters* ap = (*it)->alignmentParameters();
00216 int nsel = ap->numSelected();
00217 AlgebraicVector subvec = parameters.sub( ipos, ipos+nsel-1 );
00218 AlgebraicSymMatrix subcov = covariance.sub( ipos, ipos+nsel-1 );
00219 AlignmentParameters* apnew = ap->cloneFromSelected( subvec, subcov );
00220 (*it)->setAlignmentParameters( apnew );
00221
00222
00223 if ( updateCorrelations )
00224 {
00225 int jpos = 1;
00226 for( align::Alignables::const_iterator it2 = alignables.begin(); it2 != it; ++it2 )
00227 {
00228 theCorrelationsStore->setCorrelations( *it, *it2, covariance, ipos-1, jpos-1 );
00229 jpos += (*it2)->alignmentParameters()->numSelected();
00230 }
00231 }
00232
00233 ipos+=nsel;
00234 }
00235
00236 }
00237
00238
00239
00240 align::Alignables AlignmentParameterStore::validAlignables(void) const
00241 {
00242 align::Alignables result;
00243 for (align::Alignables::const_iterator iali = theAlignables.begin();
00244 iali != theAlignables.end(); ++iali)
00245 if ( (*iali)->alignmentParameters()->isValid() ) result.push_back(*iali);
00246
00247 LogDebug("Alignment") << "@SUB=AlignmentParameterStore::validAlignables"
00248 << "Valid alignables: " << result.size()
00249 << "out of " << theAlignables.size();
00250 return result;
00251 }
00252
00253
00254 Alignable* AlignmentParameterStore::alignableFromAlignableDet( AlignableDetOrUnitPtr alignableDet ) const
00255 {
00256 Alignable *mother = alignableDet;
00257 while (mother) {
00258 if (mother->alignmentParameters()) return mother;
00259 mother = mother->mother();
00260 }
00261
00262 return 0;
00263 }
00264
00265
00266 void AlignmentParameterStore::applyParameters(void)
00267 {
00268 align::Alignables::const_iterator iali;
00269 for ( iali = theAlignables.begin(); iali != theAlignables.end(); ++iali)
00270 applyParameters( *iali );
00271 }
00272
00273
00274
00275 void AlignmentParameterStore::applyParameters(Alignable* alignable)
00276 {
00277
00278 AlignmentParameters *pars = (alignable ? alignable->alignmentParameters() : 0);
00279 if (!pars) {
00280 throw cms::Exception("BadAlignable")
00281 << "applyParameters: provided alignable does not have alignment parameters";
00282 }
00283 pars->apply();
00284 }
00285
00286
00287
00288 void AlignmentParameterStore::resetParameters(void)
00289 {
00290
00291 theCorrelationsStore->resetCorrelations();
00292
00293
00294 align::Alignables::const_iterator iali;
00295 for ( iali = theAlignables.begin(); iali != theAlignables.end(); ++iali )
00296 resetParameters( *iali );
00297 }
00298
00299
00300
00301 void AlignmentParameterStore::resetParameters( Alignable* ali )
00302 {
00303 if ( ali )
00304 {
00305
00306 AlignmentParameters* ap = ali->alignmentParameters();
00307 if ( ap )
00308 {
00309 int npar=ap->numSelected();
00310
00311 AlgebraicVector par(npar,0);
00312 AlgebraicSymMatrix cov(npar,0);
00313 AlignmentParameters* apnew = ap->cloneFromSelected(par,cov);
00314 ali->setAlignmentParameters(apnew);
00315 apnew->setValid(false);
00316 }
00317 else
00318 edm::LogError("BadArgument") << "@SUB=AlignmentParameterStore::resetParameters"
00319 << "alignable has no alignment parameter";
00320 }
00321 else
00322 edm::LogError("BadArgument") << "@SUB=AlignmentParameterStore::resetParameters"
00323 << "argument is NULL";
00324 }
00325
00326
00327
00328 void AlignmentParameterStore::acquireRelativeParameters(void)
00329 {
00330
00331 unsigned int nAlignables = theAlignables.size();
00332
00333 for (unsigned int i = 0; i < nAlignables; ++i)
00334 {
00335 Alignable* ali = theAlignables[i];
00336
00337 RigidBodyAlignmentParameters* ap =
00338 dynamic_cast<RigidBodyAlignmentParameters*>( ali->alignmentParameters() );
00339
00340 if ( !ap )
00341 throw cms::Exception("BadAlignable")
00342 << "acquireRelativeParameters: "
00343 << "provided alignable does not have rigid body alignment parameters";
00344
00345 AlgebraicVector par( ap->size(),0 );
00346 AlgebraicSymMatrix cov( ap->size(), 0 );
00347
00348
00349 align::LocalVector dloc = ali->surface().toLocal( ali->displacement() );
00350 par[0]=dloc.x();
00351 par[1]=dloc.y();
00352 par[2]=dloc.z();
00353
00354
00355 align::EulerAngles euloc = align::toAngles( ali->surface().toLocal( ali->rotation() ) );
00356 par[3]=euloc(1);
00357 par[4]=euloc(2);
00358 par[5]=euloc(3);
00359
00360
00361 RigidBodyAlignmentParameters* apnew = ap->clone(par,cov);
00362
00363 ali->setAlignmentParameters(apnew);
00364 }
00365 }
00366
00367
00368
00369
00370
00371
00372
00373 std::pair<int,int> AlignmentParameterStore::typeAndLayer(const Alignable* ali) const
00374 {
00375 return TrackerAlignableId().typeAndLayerFromDetId( ali->id() );
00376 }
00377
00378
00379
00380 void AlignmentParameterStore::
00381 applyAlignableAbsolutePositions( const align::Alignables& alivec,
00382 const AlignablePositions& newpos,
00383 int& ierr )
00384 {
00385 unsigned int nappl=0;
00386 ierr=0;
00387
00388
00389 for (align::Alignables::const_iterator iali = alivec.begin(); iali != alivec.end(); ++iali) {
00390 Alignable* ali = *iali;
00391 align::ID id = ali->id();
00392 align::StructureType typeId = ali->alignableObjectId();
00393
00394
00395 bool found=false;
00396 for (AlignablePositions::const_iterator ipos = newpos.begin(); ipos != newpos.end(); ++ipos) {
00397 if (id == ipos->id() && typeId == ipos->objId()) {
00398 if (found) {
00399 edm::LogError("DuplicatePosition")
00400 << "New positions for alignable found more than once!";
00401 } else {
00402
00403 const align::PositionType& pnew = ipos->pos();
00404 const align::RotationType& rnew = ipos->rot();
00405
00406 const align::PositionType& pold = ali->globalPosition();
00407 const align::RotationType& rold = ali->globalRotation();
00408
00409
00410 align::GlobalVector posDiff = pnew - pold;
00411 align::RotationType rotDiff = rold.multiplyInverse(rnew);
00412 align::rectify(rotDiff);
00413 ali->move( posDiff );
00414 ali->rotateInGlobalFrame( rotDiff );
00415 LogDebug("NewPosition") << "moving by:" << posDiff;
00416 LogDebug("NewRotation") << "rotating by:\n" << rotDiff;
00417
00418
00419
00420
00421
00422
00423 found=true;
00424 ++nappl;
00425 }
00426 }
00427 }
00428 }
00429
00430 if ( nappl< newpos.size() )
00431 edm::LogError("Mismatch") << "Applied only " << nappl << " new positions"
00432 << " out of " << newpos.size();
00433
00434 LogDebug("NewPositions") << "Applied new positions for " << nappl
00435 << " out of " << alivec.size() <<" alignables.";
00436
00437 }
00438
00439
00440
00441 void AlignmentParameterStore::
00442 applyAlignableRelativePositions( const align::Alignables& alivec, const AlignableShifts& shifts, int& ierr )
00443 {
00444
00445 ierr=0;
00446 unsigned int nappl=0;
00447 unsigned int nAlignables = alivec.size();
00448
00449 for (unsigned int i = 0; i < nAlignables; ++i) {
00450 Alignable* ali = alivec[i];
00451
00452 align::ID id = ali->id();
00453 align::StructureType typeId = ali->alignableObjectId();
00454
00455
00456 bool found = false;
00457 for (AlignableShifts::const_iterator ipos = shifts.begin(); ipos != shifts.end(); ++ipos) {
00458 if (id == ipos->id() && typeId == ipos->objId()) {
00459 if (found) {
00460 edm::LogError("DuplicatePosition")
00461 << "New positions for alignable found more than once!";
00462 } else {
00463 ali->move( ipos->pos() );
00464 ali->rotateInGlobalFrame( ipos->rot() );
00465
00466
00467
00468
00469
00470
00471 found=true;
00472 ++nappl;
00473 }
00474 }
00475 }
00476 }
00477
00478 if ( nappl < shifts.size() )
00479 edm::LogError("Mismatch") << "Applied only " << nappl << " new positions"
00480 << " out of " << shifts.size();
00481
00482 LogDebug("NewPositions") << "Applied new positions for " << nappl << " alignables.";
00483 }
00484
00485
00486
00487
00488 void AlignmentParameterStore::attachAlignmentParameters( const Parameters& parvec, int& ierr )
00489 {
00490 attachAlignmentParameters( theAlignables, parvec, ierr);
00491 }
00492
00493
00494
00495
00496 void AlignmentParameterStore::attachAlignmentParameters( const align::Alignables& alivec,
00497 const Parameters& parvec, int& ierr )
00498 {
00499 int ipass = 0;
00500 int ifail = 0;
00501 ierr = 0;
00502
00503
00504 for ( align::Alignables::const_iterator iali = alivec.begin(); iali != alivec.end(); ++iali )
00505 {
00506
00507 bool found=false;
00508 for ( Parameters::const_iterator ipar = parvec.begin(); ipar != parvec.end(); ++ipar)
00509 {
00510
00511 AlignmentParameters* ap = *ipar;
00512
00513
00514 if ( ap->alignable() == (*iali) )
00515 {
00516 if (!found)
00517 {
00518 (*iali)->setAlignmentParameters(ap);
00519 ++ipass;
00520 found=true;
00521 }
00522 else edm::LogError("Alignment") << "@SUB=AlignmentParameterStore::attachAlignmentParameters"
00523 << "More than one parameters for Alignable.";
00524 }
00525 }
00526 if (!found) ++ifail;
00527 }
00528 if (ifail>0) ierr=-1;
00529
00530 LogDebug("attachAlignmentParameters") << " Parameters, Alignables: " << parvec.size() << ","
00531 << alivec.size() << "\n pass,fail: " << ipass << ","<< ifail;
00532 }
00533
00534
00535
00536 void AlignmentParameterStore::attachCorrelations( const Correlations& cormap,
00537 bool overwrite, int& ierr )
00538 {
00539 attachCorrelations( theAlignables, cormap, overwrite, ierr );
00540 }
00541
00542
00543
00544 void AlignmentParameterStore::attachCorrelations( const align::Alignables& alivec,
00545 const Correlations& cormap,
00546 bool overwrite, int& ierr )
00547 {
00548 ierr=0;
00549 int icount=0;
00550
00551
00552 for ( Correlations::const_iterator icor = cormap.begin(); icor!=cormap.end(); ++icor )
00553 {
00554 AlgebraicMatrix mat=(*icor).second;
00555 Alignable* ali1 = (*icor).first.first;
00556 Alignable* ali2 = (*icor).first.second;
00557
00558
00559 if ( find( alivec.begin(), alivec.end(), ali1 ) != alivec.end() &&
00560 find( alivec.begin(), alivec.end(), ali2 ) != alivec.end() )
00561 {
00562
00563 if ( !theCorrelationsStore->correlationsAvailable(ali1,ali2) || (overwrite) )
00564 {
00565 theCorrelationsStore->setCorrelations(ali1,ali2,mat);
00566 ++icount;
00567 }
00568 else edm::LogInfo("AlreadyExists") << "Correlation existing and not overwritten";
00569 }
00570 else edm::LogInfo("IgnoreCorrelation") << "Ignoring correlation with no alignables!";
00571 }
00572
00573 LogDebug( "attachCorrelations" ) << " Alignables,Correlations: " << alivec.size() <<","<< cormap.size()
00574 << "\n applied: " << icount ;
00575
00576 }
00577
00578
00579
00580 void AlignmentParameterStore::
00581 attachUserVariables( const align::Alignables& alivec,
00582 const std::vector<AlignmentUserVariables*>& uvarvec, int& ierr )
00583 {
00584 ierr=0;
00585
00586 LogDebug("DumpArguments") << "size of alivec: " << alivec.size()
00587 << "\nsize of uvarvec: " << uvarvec.size();
00588
00589 std::vector<AlignmentUserVariables*>::const_iterator iuvar=uvarvec.begin();
00590
00591 for ( align::Alignables::const_iterator iali=alivec.begin(); iali!=alivec.end(); ++iali, ++iuvar )
00592 {
00593 AlignmentParameters* ap = (*iali)->alignmentParameters();
00594 AlignmentUserVariables* uvarnew = (*iuvar);
00595 ap->setUserVariables(uvarnew);
00596 }
00597 }
00598
00599
00600
00601 void AlignmentParameterStore::setAlignmentPositionError( const align::Alignables& alivec,
00602 double valshift, double valrot )
00603 {
00604 unsigned int nAlignables = alivec.size();
00605
00606 for (unsigned int i = 0; i < nAlignables; ++i)
00607 {
00608 Alignable* ali = alivec[i];
00609
00610
00611 AlignmentPositionError nulApe(0,0,0);
00612 ali->setAlignmentPositionError(nulApe, true);
00613
00614
00615 AlignmentPositionError ape(valshift,valshift,valshift);
00616 if ( valshift > 0. ) ali->addAlignmentPositionError(ape, true);
00617 else ali->setAlignmentPositionError(ape, true);
00618
00619
00620
00621
00622
00623 align::EulerAngles r(3);
00624 r(1)=valrot; r(2)=valrot; r(3)=valrot;
00625 ali->addAlignmentPositionErrorFromRotation(align::toMatrix(r), true);
00626 }
00627
00628 LogDebug("StoreAPE") << "Store APE from shift: " << valshift
00629 << "\nStore APE from rotation: " << valrot;
00630 }
00631
00632
00633 bool AlignmentParameterStore
00634 ::hierarchyConstraints(const Alignable *ali, const align::Alignables &aliComps,
00635 std::vector<std::vector<ParameterId> > ¶mIdsVecOut,
00636 std::vector<std::vector<double> > &factorsVecOut,
00637 bool all, double epsilon) const
00638 {
00639
00640
00641
00642 if (!ali || !ali->alignmentParameters()) return false;
00643
00644 const std::vector<bool> &aliSel= ali->alignmentParameters()->selector();
00645 paramIdsVecOut.clear();
00646 factorsVecOut.clear();
00647
00648 bool firstComp = true;
00649 for (align::Alignables::const_iterator iComp = aliComps.begin(), iCompE = aliComps.end();
00650 iComp != iCompE; ++iComp) {
00651
00652 const ParametersToParametersDerivatives p2pDerivs(**iComp, *ali);
00653 if (!p2pDerivs.isOK()) {
00654 throw cms::Exception("BadConfig")
00655 << "AlignmentParameterStore::hierarchyConstraints"
00656 << " Bad match of types of AlignmentParameters classes.\n";
00657 return false;
00658 }
00659 const std::vector<bool> &aliCompSel = (*iComp)->alignmentParameters()->selector();
00660 for (unsigned int iParMast = 0, iParMastUsed = 0; iParMast < aliSel.size(); ++iParMast) {
00661 if (!all && !aliSel[iParMast]) continue;
00662 if (firstComp) {
00663 paramIdsVecOut.push_back(std::vector<ParameterId>());
00664 factorsVecOut.push_back(std::vector<double>());
00665 }
00666 for (unsigned int iParComp = 0; iParComp < aliCompSel.size(); ++iParComp) {
00667 if (aliCompSel[iParComp]) {
00668 const double factor = p2pDerivs(iParMast, iParComp);
00669 if (fabs(factor) > epsilon) {
00670 paramIdsVecOut[iParMastUsed].push_back(ParameterId(*iComp, iParComp));
00671 factorsVecOut[iParMastUsed].push_back(factor);
00672 }
00673 }
00674 }
00675 ++iParMastUsed;
00676 }
00677 firstComp = false;
00678 }
00679
00680 return true;
00681 }