CMS 3D CMS Logo

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