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