CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_0/src/Alignment/CommonAlignment/src/AlignableModifier.cc

Go to the documentation of this file.
00001 #include <memory>
00002 
00003 #include "CLHEP/Random/DRand48Engine.h"
00004 #include "CLHEP/Random/RandGauss.h"
00005 #include "CLHEP/Random/Randomize.h"
00006 
00007 #include "DataFormats/TrackingRecHit/interface/AlignmentPositionError.h"
00008 #include "FWCore/ServiceRegistry/interface/Service.h"
00009 #include "FWCore/Utilities/interface/RandomNumberGenerator.h"
00010 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00011 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00012 
00013 #include "Alignment/CommonAlignment/interface/AlignableComposite.h"
00014 #include "Alignment/CommonAlignment/interface/AlignableModifier.h"
00015 
00016 #include "Geometry/CommonTopologies/interface/SurfaceDeformationFactory.h"
00017 #include "Geometry/CommonTopologies/interface/SurfaceDeformation.h"
00018 
00019 //__________________________________________________________________________________________________
00020 AlignableModifier::AlignableModifier( void ) :
00021   distribution_(""),
00022   random_(false), gaussian_(false), setError_(false),
00023   setRotations_(false),setTranslations_(false),
00024   seed_(0),
00025   scaleError_(0.), scale_(0.),
00026   phiX_(0.), phiY_(0.), phiZ_(0.),
00027   phiXlocal_(0.), phiYlocal_(0.), phiZlocal_(0.),
00028   dX_(0.), dY_(0.), dZ_(0.),
00029   dXlocal_(0.), dYlocal_(0.), dZlocal_(0.),
00030   twist_(0.), shear_(0.)
00031 {
00032 
00033   theDRand48Engine = new CLHEP::DRand48Engine();
00034 
00035 }
00036 
00037 
00038 //__________________________________________________________________________________________________
00039 AlignableModifier::~AlignableModifier()
00040 {
00041 
00042   delete theDRand48Engine;
00043 
00044 }
00045 
00046 //__________________________________________________________________________________________________
00047 void AlignableModifier::init_( void )
00048 {
00049 
00050   // Initialize all known parameters (according to ORCA's MisalignmentScenario.cc)
00051   distribution_ = "";        // Switch for distributions ("fixed","flat","gaussian")
00052   setError_     = false;     // Apply alignment errors
00053   setRotations_ = true;      // Apply rotations
00054   setTranslations_ = true;   // Apply translations
00055   scale_        = 1.;        // Scale to apply to all movements
00056   scaleError_   = 1.;        // Scale to apply to alignment errors
00057   phiX_         = 0.;        // Rotation angle around X [rad]
00058   phiY_         = 0.;        // Rotation angle around Y [rad]
00059   phiZ_         = 0.;        // Rotation angle around Z [rad]
00060   phiXlocal_    = 0.;        // Local rotation angle around X [rad]
00061   phiYlocal_    = 0.;        // Local rotation angle around Y [rad]
00062   phiZlocal_    = 0.;        // Local rotation angle around Z [rad]
00063   dX_           = 0.;        // X displacement [cm]
00064   dY_           = 0.;        // Y displacement [cm]
00065   dZ_           = 0.;        // Z displacement [cm]
00066   dXlocal_      = 0.;        // Local X displacement [cm]
00067   dYlocal_      = 0.;        // Local Y displacement [cm]
00068   dZlocal_      = 0.;        // Local Z displacement [cm]
00069   deformation_.first.clear();// SurfaceDeformation: type
00070   deformation_.second.clear();//SurfaceDeformation: parameter vector
00071   twist_        = 0.;        // Twist angle [rad]
00072   shear_        = 0.;        // Shear angle [rad]
00073 
00074   // These are set through 'distribution'
00075   random_       = true;      // Use random distributions
00076   gaussian_     = true;      // Use gaussian distribution (otherwise flat)
00077 
00078 }
00079 
00080 //__________________________________________________________________________________________________
00081 // Return true if given parameter name should be propagated down
00082 bool AlignableModifier::isPropagated( const std::string& parameterName ) const
00083 {
00084 
00085   if ( parameterName == "distribution"    || 
00086        parameterName == "setError"        ||
00087        parameterName == "scaleError"      ||
00088        parameterName == "setRotations"    ||
00089        parameterName == "setTranslations" ||
00090        parameterName == "scale" 
00091        ) return true;
00092   
00093   return false;
00094 
00095 }
00096 
00097 
00098 //__________________________________________________________________________________________________
00100 bool AlignableModifier::modify( Alignable* alignable, const edm::ParameterSet& pSet )
00101 {
00102 
00103   // Initialize parameters
00104   this->init_();
00105   int rotX_=0, rotY_=0, rotZ_=0; // To check correct backward compatibility
00106 
00107 
00108   // Reset counter
00109   m_modified = 0;
00110   
00111   // Retrieve parameters
00112   std::ostringstream error;
00113   std::vector<std::string> parameterNames = pSet.getParameterNames();
00114   for ( std::vector<std::string>::iterator iParam = parameterNames.begin(); 
00115         iParam != parameterNames.end(); iParam++ ) {
00116     if  ( (*iParam) == "distribution" ) distribution_ = pSet.getParameter<std::string>( *iParam );
00117     else if ( (*iParam) == "setError" ) setError_ = pSet.getParameter<bool>( *iParam );
00118     else if ( (*iParam) == "setRotations") setRotations_ = pSet.getParameter<bool>( *iParam );
00119     else if ( (*iParam) == "setTranslations") setTranslations_ = pSet.getParameter<bool>( *iParam );
00120     else if ( (*iParam) == "scale" )    scale_ = pSet.getParameter<double>( *iParam );
00121     else if ( (*iParam) == "scaleError" ) scaleError_ = pSet.getParameter<double>( *iParam );
00122     else if ( (*iParam) == "phiX" )    phiX_     = pSet.getParameter<double>( *iParam );
00123     else if ( (*iParam) == "phiY" )    phiY_     = pSet.getParameter<double>( *iParam );
00124     else if ( (*iParam) == "phiZ" )    phiZ_     = pSet.getParameter<double>( *iParam );
00125     else if ( (*iParam) == "dX" )      dX_       = pSet.getParameter<double>( *iParam );
00126     else if ( (*iParam) == "dY" )      dY_       = pSet.getParameter<double>( *iParam );
00127     else if ( (*iParam) == "dZ" )      dZ_       = pSet.getParameter<double>( *iParam );
00128     else if ( (*iParam) == "dXlocal" ) dXlocal_  = pSet.getParameter<double>( *iParam );
00129     else if ( (*iParam) == "dYlocal" ) dYlocal_  = pSet.getParameter<double>( *iParam );
00130     else if ( (*iParam) == "dZlocal" ) dZlocal_  = pSet.getParameter<double>( *iParam );
00131     else if ( (*iParam) == "twist" )   twist_    = pSet.getParameter<double>( *iParam );
00132     else if ( (*iParam) == "shear" )   shear_    = pSet.getParameter<double>( *iParam );
00133     else if ( (*iParam) == "localX" ) { phiXlocal_=pSet.getParameter<double>( *iParam ); rotX_++; }
00134     else if ( (*iParam) == "localY" ) { phiYlocal_=pSet.getParameter<double>( *iParam ); rotY_++; }
00135     else if ( (*iParam) == "localZ" ) { phiZlocal_=pSet.getParameter<double>( *iParam ); rotZ_++; }
00136     else if ( (*iParam) == "phiXlocal" ) { phiXlocal_=pSet.getParameter<double>( *iParam ); rotX_++; }
00137     else if ( (*iParam) == "phiYlocal" ) { phiYlocal_=pSet.getParameter<double>( *iParam ); rotY_++; }
00138     else if ( (*iParam) == "phiZlocal" ) { phiZlocal_=pSet.getParameter<double>( *iParam ); rotZ_++; }
00139     else if ( (*iParam) == "deformation" ) {
00140       const edm::ParameterSet deform(pSet.getParameter<edm::ParameterSet>( *iParam ));
00141       deformation_.first  = deform.getParameter<std::string>("type");
00142       deformation_.second = deform.getParameter<std::vector<double> >("parameters");
00143       // a non-complete check of simple mistyping of "deformation"
00144       // i.e. should detect at least a single wrong character... HACK
00145     } else if (pSet.existsAs<edm::ParameterSet>(*iParam)
00146                && ((*iParam).find("deform") != std::string::npos ||
00147                    (*iParam).find("ation")  != std::string::npos)) {
00148       throw cms::Exception("BadConfig") << "Probable mistyping in config: '" << (*iParam)
00149                                         << "' should probably mean 'deformation'\n";
00150     } else if ( !pSet.existsAs<edm::ParameterSet>(*iParam) ) { // other PSets are OK to ignore
00151       if ( !error.str().length() ) error << "Unknown parameter name(s): ";
00152       error << " " << *iParam;
00153     }
00154   }
00155 
00156   // Check if both 'localN' and 'phiNlocal' have been used
00157   if ( rotX_==2 ) throw cms::Exception("BadConfig") << "Found both localX and phiXlocal";
00158   if ( rotY_==2 ) throw cms::Exception("BadConfig") << "Found both localY and phiYlocal";
00159   if ( rotZ_==2 ) throw cms::Exception("BadConfig") << "Found both localZ and phiZlocal";
00160 
00161   // Check error
00162   if ( error.str().length() )
00163     throw cms::Exception("BadConfig") << error.str();
00164 
00165   // Decode distribution
00166   this->setDistribution( distribution_ );
00167 
00168   //if (scale_) { NO! Different random sequence if only parts scale to zero!
00169 
00170   // Apply displacements
00171   if ( std::abs(dX_) + std::abs(dY_) + std::abs(dZ_) > 0 && setTranslations_ )
00172     this->moveAlignable( alignable, random_, gaussian_, scale_*dX_, scale_*dY_, scale_*dZ_ );
00173   
00174   // Apply local displacements
00175   if ( std::abs(dXlocal_) + std::abs(dYlocal_) + std::abs(dZlocal_) > 0 && setTranslations_ )
00176     this->moveAlignableLocal( alignable, random_, gaussian_, 
00177                               scale_*dXlocal_, scale_*dYlocal_, scale_*dZlocal_ );
00178   
00179   // Apply rotations
00180   if ( std::abs(phiX_) + std::abs(phiY_) + std::abs(phiZ_) > 0 && setRotations_ )
00181     this->rotateAlignable( alignable, random_, gaussian_,
00182                            scale_*phiX_, scale_*phiY_, scale_*phiZ_ );
00183   
00184   // Apply local rotations
00185   if ( std::abs(phiXlocal_) + std::abs(phiYlocal_) + std::abs(phiZlocal_) > 0 && setRotations_ )
00186     this->rotateAlignableLocal( alignable, random_, gaussian_, 
00187                                 scale_*phiXlocal_, scale_*phiYlocal_, scale_*phiZlocal_ );
00188   
00189   // Apply twist
00190   if ( std::abs(twist_) > 0 )
00191     edm::LogError("NotImplemented") << "Twist is not implemented yet";
00192   
00193   // Apply shear
00194   if ( std::abs(shear_) > 0 )
00195     edm::LogError("NotImplemented") << "Shear is not implemented yet";
00196   
00197   if (!deformation_.first.empty()) {
00198     this->addDeformation(alignable, deformation_, random_, gaussian_, scale_);
00199   }
00200 
00201   // Apply error - first add scale_ to error
00202   scaleError_ *= scale_;
00203   if ( setError_ && scaleError_ ) {
00204     // Alignment Position Error for flat distribution: 1 sigma
00205     if ( !gaussian_ ) scaleError_ *= 0.68;
00206     
00207     
00208     // Error on displacement
00209     if ( std::abs(dX_) + std::abs(dY_) + std::abs(dZ_) > 0 && setTranslations_ )
00210       this->addAlignmentPositionError( alignable, 
00211                                        scaleError_*dX_, scaleError_*dY_, scaleError_*dZ_ );
00212     
00213     // Error on local displacements
00214     if ( std::abs(dXlocal_) + std::abs(dYlocal_) + std::abs(dZlocal_) > 0 && setTranslations_ )
00215       this->addAlignmentPositionErrorLocal( alignable,
00216                                             scaleError_*dXlocal_, scaleError_*dYlocal_, 
00217                                             scaleError_*dZlocal_ );
00218     
00219     // Error on rotations
00220     if ( std::abs(phiX_) + std::abs(phiY_) + std::abs(phiZ_) > 0 && setRotations_ )
00221       this->addAlignmentPositionErrorFromRotation( alignable, 
00222                                                    scaleError_*phiX_, scaleError_*phiY_, 
00223                                                    scaleError_*phiZ_ );
00224     
00225     // Error on local rotations
00226     if ( std::abs(phiXlocal_) + std::abs(phiYlocal_) + std::abs(phiZlocal_) > 0
00227          && setRotations_ )
00228       this->addAlignmentPositionErrorFromLocalRotation( alignable, 
00229                                                         scaleError_*phiXlocal_, 
00230                                                         scaleError_*phiYlocal_, 
00231                                                         scaleError_*phiZlocal_ );
00232     // Do we need to add any APE for deformations?
00233     // Probably we would do so if there wouldn't be data, but only MC to play with... ;-)
00234   }
00235   // } // end if (scale_)
00236 
00237   return ( m_modified > 0 );
00238   
00239 }
00240 
00241 
00242 //__________________________________________________________________________________________________
00243 void AlignableModifier::setDistribution( const std::string& distr )
00244 {
00245 
00246   if ( distr == "fixed" ) random_ = false;
00247   else if ( distr == "flat" ) {
00248     random_   = true;
00249     gaussian_ = false;
00250   } else if ( distr == "gaussian" ) {
00251     random_   = true;
00252     gaussian_ = true;
00253   }
00254   
00255 }
00256 
00257 
00258 //__________________________________________________________________________________________________
00260 void AlignableModifier::setSeed( const long seed )
00261 {
00262 
00263   long m_seed;
00264 
00265   if ( seed > 0 ) m_seed = seed;
00266   else {
00267     edm::Service<edm::RandomNumberGenerator> rng;
00268     m_seed = rng->mySeed();
00269   }
00270 
00271   LogDebug("PrintArgs") << "Setting generator seed to " << m_seed;
00272 
00273   theDRand48Engine->setSeed( m_seed );
00274 
00275 }
00276 
00277 //__________________________________________________________________________________________________
00280 void AlignableModifier::moveAlignable( Alignable* alignable, bool random, bool gaussian,
00281                                        float sigmaX, float sigmaY, float sigmaZ )
00282 {
00283 
00284   
00285   std::ostringstream message;
00286  
00287   // Get movement vector according to arguments
00288   GlobalVector moveV( sigmaX, sigmaY, sigmaZ ); // Default: fixed
00289   if ( random ) {
00290     std::vector<float> randomNumbers;
00291     message << "random ";
00292     if (gaussian)       {
00293       randomNumbers = this->gaussianRandomVector( sigmaX, sigmaY, sigmaZ );
00294       message << "gaussian ";
00295     } else      {
00296       randomNumbers = this->flatRandomVector( sigmaX, sigmaY, sigmaZ );
00297       message << "flat ";
00298     }
00299     moveV = GlobalVector( randomNumbers[0], randomNumbers[1], randomNumbers[2] );
00300   }
00301   
00302   message << " move with sigma " << sigmaX << " " << sigmaY << " " << sigmaZ;
00303 
00304   LogDebug("PrintArgs") << message.str(); // Arguments
00305 
00306   LogDebug("PrintMovement") << "applied displacement: " << moveV; // Actual movements
00307   alignable->move(moveV);
00308   m_modified++;
00309 
00310 
00311 }
00312 
00313 //__________________________________________________________________________________________________
00316 void AlignableModifier::moveAlignableLocal( Alignable* alignable, bool random, bool gaussian,
00317                                             float sigmaX, float sigmaY, float sigmaZ )
00318 {
00319 
00320   
00321   std::ostringstream message;
00322  
00323   // Get movement vector according to arguments
00324   align::LocalVector moveV( sigmaX, sigmaY, sigmaZ ); // Default: fixed
00325   if ( random ) {
00326     std::vector<float> randomNumbers;
00327     message << "random ";
00328     if (gaussian) {
00329       randomNumbers = this->gaussianRandomVector( sigmaX, sigmaY, sigmaZ );
00330       message << "gaussian ";
00331     } else {
00332       randomNumbers = this->flatRandomVector( sigmaX, sigmaY, sigmaZ );
00333       message << "flat ";
00334     }
00335     moveV = align::LocalVector( randomNumbers[0], randomNumbers[1], randomNumbers[2] );
00336   }
00337   
00338   message << " move with sigma " << sigmaX << " " << sigmaY << " " << sigmaZ;
00339 
00340   LogDebug("PrintArgs") << message.str(); // Arguments
00341 
00342   LogDebug("PrintMovement") << "applied local displacement: " << moveV; // Actual movements
00343   alignable->move( alignable->surface().toGlobal(moveV) );
00344   m_modified++;
00345 
00346 
00347 }
00348 
00349 //__________________________________________________________________________________________________
00350 void AlignableModifier
00351 ::addDeformation(Alignable *alignable,
00352                 const AlignableModifier::DeformationMemberType &deformation,
00353                 bool random, bool gaussian, double scale)
00354 {
00355   const SurfaceDeformationFactory::Type deformType
00356     = SurfaceDeformationFactory::surfaceDeformationType(deformation.first);
00357 
00358   // Scale and randomize
00359   // (need a little hack since ySplit must not be treated)!
00360   const bool rndNotLast = (deformType == SurfaceDeformationFactory::kTwoBowedSurfaces);
00361   std::vector<double> rndDeformation(deformation.second.begin(),
00362                                      deformation.second.end() - (rndNotLast ? 1 : 0));
00363   for (unsigned int i = 0; i < rndDeformation.size(); ++i) {
00364     rndDeformation[i] *= scale;
00365   }
00366   if (random) {
00367     this->randomise(rndDeformation, gaussian);
00368   }
00369   if (rndNotLast) { // put back ySplit at the end
00370     rndDeformation.push_back(deformation.second.back());
00371   }
00372   
00373   // auto_ptr has exception safe delete (in contrast to bare pointer)
00374   const std::auto_ptr<SurfaceDeformation> surfDef
00375     (SurfaceDeformationFactory::create(deformType, rndDeformation));
00376   
00377   alignable->addSurfaceDeformation(surfDef.get(), true); // true to propagate down
00378   ++m_modified;
00379 }
00380 
00381 //__________________________________________________________________________________________________
00384 void AlignableModifier::rotateAlignable( Alignable* alignable, bool random, bool gaussian,
00385                                          float sigmaPhiX, float sigmaPhiY, float sigmaPhiZ )
00386 {
00387 
00388   
00389   std::ostringstream message;
00390 
00391   // Get rotation vector according to arguments
00392   GlobalVector rotV( sigmaPhiX, sigmaPhiY, sigmaPhiZ ); // Default: fixed
00393   if ( random ) {
00394     std::vector<float> randomNumbers;
00395     message << "random ";
00396     if (gaussian) {
00397       randomNumbers = this->gaussianRandomVector( sigmaPhiX, sigmaPhiY, sigmaPhiZ );
00398       message << "gaussian ";
00399     } else {
00400       randomNumbers = flatRandomVector( sigmaPhiX, sigmaPhiY, sigmaPhiZ );
00401       message << "flat ";
00402     }
00403     rotV = GlobalVector( randomNumbers[0], randomNumbers[1], randomNumbers[2] );
00404   }
00405   
00406   message << "global rotation by angles " << sigmaPhiX << " " << sigmaPhiY << " " << sigmaPhiZ;
00407 
00408   LogDebug("PrintArgs") << message.str(); // Arguments
00409 
00410   LogDebug("PrintMovement") << "applied rotation angles: " << rotV; // Actual movements
00411   if ( std::abs(sigmaPhiX) ) alignable->rotateAroundGlobalX( rotV.x() );
00412   if ( std::abs(sigmaPhiY) ) alignable->rotateAroundGlobalY( rotV.y() );
00413   if ( std::abs(sigmaPhiZ) ) alignable->rotateAroundGlobalZ( rotV.z() );
00414   m_modified++;
00415 
00416 
00417 }
00418 
00419 //__________________________________________________________________________________________________
00422 void 
00423 AlignableModifier::rotateAlignableLocal( Alignable* alignable, bool random, bool gaussian,
00424                                          float sigmaPhiX, float sigmaPhiY, float sigmaPhiZ )
00425 {
00426 
00427   
00428   std::ostringstream message;
00429 
00430   // Get rotation vector according to arguments
00431   align::LocalVector rotV( sigmaPhiX, sigmaPhiY, sigmaPhiZ ); // Default: fixed
00432   if ( random ) {
00433     std::vector<float> randomNumbers;
00434     message << "random ";
00435     if (gaussian) {
00436       randomNumbers = this->gaussianRandomVector( sigmaPhiX, sigmaPhiY, sigmaPhiZ );
00437       message << "gaussian ";
00438     } else {
00439       randomNumbers = flatRandomVector( sigmaPhiX, sigmaPhiY, sigmaPhiZ );
00440       message << "flat ";
00441     }
00442     rotV = align::LocalVector( randomNumbers[0], randomNumbers[1], randomNumbers[2] );
00443   }
00444   
00445   message << "local rotation by angles " << sigmaPhiX << " " << sigmaPhiY << " " << sigmaPhiZ;
00446   
00447   LogDebug("PrintArgs") << message.str(); // Arguments
00448   
00449   LogDebug("PrintMovement") << "applied local rotation angles: " << rotV; // Actual movements
00450   if ( std::abs(sigmaPhiX) ) alignable->rotateAroundLocalX( rotV.x() );
00451   if ( std::abs(sigmaPhiY) ) alignable->rotateAroundLocalY( rotV.y() );
00452   if ( std::abs(sigmaPhiZ) ) alignable->rotateAroundLocalZ( rotV.z() );
00453   m_modified++;
00454 
00455 
00456 }
00457 
00458 
00459 //__________________________________________________________________________________________________
00460 const std::vector<float> 
00461 AlignableModifier::gaussianRandomVector( float sigmaX, float sigmaY, float sigmaZ ) const
00462 {
00463 
00464   // Get absolute value if negative arguments
00465   if ( sigmaX < 0 ) {
00466     edm::LogWarning("BadConfig") << " taking absolute value for gaussian sigma_x";
00467     sigmaX = std::abs(sigmaX);
00468   }
00469   if ( sigmaY < 0 ) {
00470     edm::LogWarning("BadConfig") << " taking absolute value for gaussian sigma_y";
00471     sigmaY = std::abs(sigmaY);
00472   }
00473   if ( sigmaZ < 0 ) {
00474     edm::LogWarning("BadConfig") << " taking absolute value for gaussian sigma_z";
00475     sigmaZ = std::abs(sigmaZ);
00476   }
00477 
00478   // Pass by reference, otherwise pointer is deleted!
00479   CLHEP::RandGauss aGaussObjX( *theDRand48Engine, 0., sigmaX );
00480   CLHEP::RandGauss aGaussObjY( *theDRand48Engine, 0., sigmaY );
00481   CLHEP::RandGauss aGaussObjZ( *theDRand48Engine, 0., sigmaZ );
00482 
00483   std::vector<float> randomVector;
00484   randomVector.push_back( aGaussObjX.fire() );
00485   randomVector.push_back( aGaussObjY.fire() );
00486   randomVector.push_back( aGaussObjZ.fire() );
00487 
00488   return randomVector;
00489 
00490 }
00491 
00492 
00493 //__________________________________________________________________________________________________
00494 const  std::vector<float> 
00495 AlignableModifier::flatRandomVector( float sigmaX,float sigmaY, float sigmaZ ) const
00496 {
00497 
00498   // Get absolute value if negative arguments
00499   if ( sigmaX < 0 ) {
00500     edm::LogWarning("BadConfig") << " taking absolute value for flat sigma_x";
00501     sigmaX = std::abs(sigmaX);
00502   }
00503   if ( sigmaY < 0 ) {
00504     edm::LogWarning("BadConfig") << " taking absolute value for flat sigma_y";
00505     sigmaY = std::abs(sigmaY);
00506   }
00507   if ( sigmaZ < 0 ) {
00508     edm::LogWarning("BadConfig") << " taking absolute value for flat sigma_z";
00509     sigmaZ = std::abs(sigmaZ);
00510   }
00511 
00512   CLHEP::RandFlat aFlatObjX( *theDRand48Engine, -sigmaX, sigmaX );
00513   CLHEP::RandFlat aFlatObjY( *theDRand48Engine, -sigmaY, sigmaY );
00514   CLHEP::RandFlat aFlatObjZ( *theDRand48Engine, -sigmaZ, sigmaZ );
00515 
00516   std::vector<float> randomVector;
00517   randomVector.push_back( aFlatObjX.fire() );
00518   randomVector.push_back( aFlatObjY.fire() );
00519   randomVector.push_back( aFlatObjZ.fire() );
00520 
00521   return randomVector;
00522 
00523 }
00524 
00525 //__________________________________________________________________________________________________
00526 void AlignableModifier::randomise(std::vector<double> &rnd, bool gaussian) const
00527 {
00528   for (unsigned int i = 0; i < rnd.size(); ++i) {
00529     if (rnd[i] < 0.)  {
00530       edm::LogWarning("BadConfig") << " taking absolute value to randomise " << i;
00531       rnd[i] = std::abs(rnd[i]);
00532     }
00533     
00534     if (gaussian) {
00535       CLHEP::RandGauss aGaussObj( *theDRand48Engine, 0., rnd[i]);
00536       rnd[i] = aGaussObj.fire();
00537     } else {
00538       CLHEP::RandFlat aFlatObj(*theDRand48Engine, -rnd[i], rnd[i]);
00539       rnd[i] = aFlatObj.fire();
00540     }
00541   }
00542 }
00543 
00544 //__________________________________________________________________________________________________
00545 void AlignableModifier::addAlignmentPositionError( Alignable* alignable, 
00546                                                    float dx, float dy, float dz )
00547 {
00548 
00549   LogDebug("PrintArgs") << "Adding an AlignmentPositionError of size " 
00550                         << dx << " "  << dy << " "  << dz;
00551 
00552   AlignmentPositionError ape(dx,dy,dz);
00553   alignable->addAlignmentPositionError( ape, true );
00554 
00555 }
00556 
00557 
00558 //__________________________________________________________________________________________________
00559 void AlignableModifier::addAlignmentPositionErrorLocal( Alignable* alignable, 
00560                                                         float dx, float dy, float dz )
00561 {
00562 
00563   LogDebug("PrintArgs") << "Adding a local AlignmentPositionError of size " 
00564                         << dx << " "  << dy << " "  << dz;
00565 
00566   AlgebraicSymMatrix as(3,0); //3x3, zeroed
00567   as[0][0] = dx*dx; as[1][1] = dy*dy; as[2][2] = dz*dz; //diagonals
00568   align::RotationType rt = alignable->globalRotation(); //get rotation
00569   AlgebraicMatrix am(3,3);
00570   am[0][0]=rt.xx(); am[0][1]=rt.xy(); am[0][2]=rt.xz();
00571   am[1][0]=rt.yx(); am[1][1]=rt.yy(); am[1][2]=rt.yz();
00572   am[2][0]=rt.zx(); am[2][1]=rt.zy(); am[2][2]=rt.zz();
00573   as=as.similarityT(am); //rotate error matrix
00574 
00575   GlobalError ge( asSMatrix<3>(as) );
00576   AlignmentPositionError ape( ge );
00577 
00578   alignable->addAlignmentPositionError( ape, true ); // propagate down to components
00579 
00580 }
00581 
00582 
00583 
00584 //__________________________________________________________________________________________________
00585 void AlignableModifier::addAlignmentPositionErrorFromRotation( Alignable* alignable, 
00586                                                                float phiX, float phiY, 
00587                                                                float phiZ )
00588 {
00589 
00590   align::RotationType rotx( Basic3DVector<float>(1.0, 0.0, 0.0), phiX );
00591   align::RotationType roty( Basic3DVector<float>(0.0, 1.0, 0.0), phiY );
00592   align::RotationType rotz( Basic3DVector<float>(0.0, 0.0, 1.0), phiZ );
00593   align::RotationType rot = rotz * roty * rotx;
00594   
00595   this->addAlignmentPositionErrorFromRotation( alignable, rot );
00596 
00597 }
00598 
00599 
00600 //__________________________________________________________________________________________________
00601 void AlignableModifier::addAlignmentPositionErrorFromLocalRotation( Alignable* alignable, 
00602                                                                     float phiX, float phiY, 
00603                                                                     float phiZ )
00604 {
00605 
00606   align::RotationType rotx( Basic3DVector<float>(1.0, 0.0, 0.0), phiX );
00607   align::RotationType roty( Basic3DVector<float>(0.0, 1.0, 0.0), phiY );
00608   align::RotationType rotz( Basic3DVector<float>(0.0, 0.0, 1.0), phiZ );
00609   align::RotationType rot = rotz * roty * rotx;
00610   
00611   this->addAlignmentPositionErrorFromLocalRotation( alignable, rot );
00612 
00613 }
00614 
00615 
00616 //__________________________________________________________________________________________________
00617 void AlignableModifier::addAlignmentPositionErrorFromRotation( Alignable* alignable, 
00618                                                                align::RotationType& rotation )
00619 { 
00620 
00621   LogDebug("PrintArgs") << "Adding an AlignmentPositionError from Rotation" << std::endl 
00622                         << rotation;
00623 
00624   alignable->addAlignmentPositionErrorFromRotation(rotation, true); // propagate down to components
00625 
00626 }
00627 
00628 
00629 //__________________________________________________________________________________________________
00630 void AlignableModifier::addAlignmentPositionErrorFromLocalRotation( Alignable* alignable, 
00631                                                                     align::RotationType& rotation )
00632 { 
00633   
00634   LogDebug("PrintArgs") << "Adding an AlignmentPositionError from Local Rotation" << std::endl 
00635                         << rotation;
00636   
00637   // true: propagate down to components
00638   alignable->addAlignmentPositionErrorFromLocalRotation(rotation, true);
00639   
00640 }
00641