CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/Alignment/CommonAlignment/src/AlignableModifier.cc

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