Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 11:56:07

0001 #include <memory>
0002 #include <cctype>
0003 
0004 #include "CLHEP/Random/DRand48Engine.h"
0005 #include "CLHEP/Random/RandGauss.h"
0006 #include "CLHEP/Random/Randomize.h"
0007 
0008 #include "DataFormats/GeometryCommonDetAlgo/interface/AlignmentPositionError.h"
0009 #include "FWCore/ServiceRegistry/interface/Service.h"
0010 #include "FWCore/Utilities/interface/RandomNumberGenerator.h"
0011 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0012 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0013 
0014 #include "Alignment/CommonAlignment/interface/AlignableComposite.h"
0015 #include "Alignment/CommonAlignment/interface/AlignableModifier.h"
0016 
0017 #include "Geometry/CommonTopologies/interface/SurfaceDeformationFactory.h"
0018 #include "Geometry/CommonTopologies/interface/SurfaceDeformation.h"
0019 
0020 //__________________________________________________________________________________________________
0021 AlignableModifier::AlignableModifier(void)
0022     : distribution_(""),
0023       random_(false),
0024       gaussian_(false),
0025       setError_(false),
0026       setRotations_(false),
0027       setTranslations_(false),
0028       seed_(0),
0029       scaleError_(0.),
0030       scale_(0.),
0031       phiX_(0.),
0032       phiY_(0.),
0033       phiZ_(0.),
0034       phiXlocal_(0.),
0035       phiYlocal_(0.),
0036       phiZlocal_(0.),
0037       dX_(0.),
0038       dY_(0.),
0039       dZ_(0.),
0040       dXlocal_(0.),
0041       dYlocal_(0.),
0042       dZlocal_(0.),
0043       twist_(0.),
0044       shear_(0.) {
0045   theDRand48Engine = new CLHEP::DRand48Engine();
0046 }
0047 
0048 //__________________________________________________________________________________________________
0049 AlignableModifier::~AlignableModifier() { delete theDRand48Engine; }
0050 
0051 //__________________________________________________________________________________________________
0052 void AlignableModifier::init_(void) {
0053   // Initialize all known parameters (according to ORCA's MisalignmentScenario.cc)
0054   distribution_ = "";           // Switch for distributions ("fixed","flat","gaussian")
0055   setError_ = false;            // Apply alignment errors
0056   setRotations_ = true;         // Apply rotations
0057   setTranslations_ = true;      // Apply translations
0058   scale_ = 1.;                  // Scale to apply to all movements
0059   scaleError_ = 1.;             // Scale to apply to alignment errors
0060   phiX_ = 0.;                   // Rotation angle around X [rad]
0061   phiY_ = 0.;                   // Rotation angle around Y [rad]
0062   phiZ_ = 0.;                   // Rotation angle around Z [rad]
0063   phiXlocal_ = 0.;              // Local rotation angle around X [rad]
0064   phiYlocal_ = 0.;              // Local rotation angle around Y [rad]
0065   phiZlocal_ = 0.;              // Local rotation angle around Z [rad]
0066   dX_ = 0.;                     // X displacement [cm]
0067   dY_ = 0.;                     // Y displacement [cm]
0068   dZ_ = 0.;                     // Z displacement [cm]
0069   dXlocal_ = 0.;                // Local X displacement [cm]
0070   dYlocal_ = 0.;                // Local Y displacement [cm]
0071   dZlocal_ = 0.;                // Local Z displacement [cm]
0072   deformation_.first.clear();   // SurfaceDeformation: type
0073   deformation_.second.clear();  //SurfaceDeformation: parameter vector
0074   twist_ = 0.;                  // Twist angle [rad]
0075   shear_ = 0.;                  // Shear angle [rad]
0076 
0077   // These are set through 'distribution'
0078   random_ = true;    // Use random distributions
0079   gaussian_ = true;  // Use gaussian distribution (otherwise flat)
0080 }
0081 
0082 //__________________________________________________________________________________________________
0083 // Return true if given parameter name should be propagated down
0084 bool AlignableModifier::isPropagated(const std::string& parameterName) const {
0085   if (parameterName == "distribution" || parameterName == "setError" || parameterName == "scaleError" ||
0086       parameterName == "setRotations" || parameterName == "setTranslations" || parameterName == "scale")
0087     return true;
0088 
0089   return false;
0090 }
0091 
0092 //__________________________________________________________________________________________________
0093 /// All known parameters and defaults are defined here! Returns true if modification actually applied.
0094 bool AlignableModifier::modify(Alignable* alignable, const edm::ParameterSet& pSet) {
0095   // Initialize parameters
0096   this->init_();
0097   int rotX_ = 0, rotY_ = 0, rotZ_ = 0;  // To check correct backward compatibility
0098 
0099   // Reset counter
0100   m_modified = 0;
0101 
0102   // Retrieve parameters
0103   std::ostringstream error;
0104   std::vector<std::string> parameterNames = pSet.getParameterNames();
0105   for (std::vector<std::string>::iterator iParam = parameterNames.begin(); iParam != parameterNames.end(); ++iParam) {
0106     if ((*iParam) == "distribution")
0107       distribution_ = pSet.getParameter<std::string>(*iParam);
0108     else if ((*iParam) == "setError")
0109       setError_ = pSet.getParameter<bool>(*iParam);
0110     else if ((*iParam) == "setRotations")
0111       setRotations_ = pSet.getParameter<bool>(*iParam);
0112     else if ((*iParam) == "setTranslations")
0113       setTranslations_ = pSet.getParameter<bool>(*iParam);
0114     else if ((*iParam) == "scale")
0115       scale_ = pSet.getParameter<double>(*iParam);
0116     else if ((*iParam) == "scaleError")
0117       scaleError_ = pSet.getParameter<double>(*iParam);
0118     else if ((*iParam) == "phiX")
0119       phiX_ = pSet.getParameter<double>(*iParam);
0120     else if ((*iParam) == "phiY")
0121       phiY_ = pSet.getParameter<double>(*iParam);
0122     else if ((*iParam) == "phiZ")
0123       phiZ_ = pSet.getParameter<double>(*iParam);
0124     else if ((*iParam) == "dX")
0125       dX_ = pSet.getParameter<double>(*iParam);
0126     else if ((*iParam) == "dY")
0127       dY_ = pSet.getParameter<double>(*iParam);
0128     else if ((*iParam) == "dZ")
0129       dZ_ = pSet.getParameter<double>(*iParam);
0130     else if ((*iParam) == "dXlocal")
0131       dXlocal_ = pSet.getParameter<double>(*iParam);
0132     else if ((*iParam) == "dYlocal")
0133       dYlocal_ = pSet.getParameter<double>(*iParam);
0134     else if ((*iParam) == "dZlocal")
0135       dZlocal_ = pSet.getParameter<double>(*iParam);
0136     else if ((*iParam) == "twist")
0137       twist_ = pSet.getParameter<double>(*iParam);
0138     else if ((*iParam) == "shear")
0139       shear_ = pSet.getParameter<double>(*iParam);
0140     else if ((*iParam) == "localX") {
0141       phiXlocal_ = pSet.getParameter<double>(*iParam);
0142       rotX_++;
0143     } else if ((*iParam) == "localY") {
0144       phiYlocal_ = pSet.getParameter<double>(*iParam);
0145       rotY_++;
0146     } else if ((*iParam) == "localZ") {
0147       phiZlocal_ = pSet.getParameter<double>(*iParam);
0148       rotZ_++;
0149     } else if ((*iParam) == "phiXlocal") {
0150       phiXlocal_ = pSet.getParameter<double>(*iParam);
0151       rotX_++;
0152     } else if ((*iParam) == "phiYlocal") {
0153       phiYlocal_ = pSet.getParameter<double>(*iParam);
0154       rotY_++;
0155     } else if ((*iParam) == "phiZlocal") {
0156       phiZlocal_ = pSet.getParameter<double>(*iParam);
0157       rotZ_++;
0158     } else if ((*iParam) == "deformation") {
0159       const edm::ParameterSet deform(pSet.getParameter<edm::ParameterSet>(*iParam));
0160       deformation_.first = deform.getParameter<std::string>("type");
0161       deformation_.second = deform.getParameter<std::vector<double> >("parameters");
0162     } else if (pSet.existsAs<edm::ParameterSet>(*iParam)) {
0163       // Other PSets than 'deformation' must refer to hierarchy structures, i.e. their name
0164       // is a level name followed by 's' or ending with a digit (see
0165       // MisalignmentScenarioBuilder::getParameterSet_). Pitfall is to forget the trailing 's'!
0166       // 'Muon' is an especially allowed case used in MuonScenarioBuilder::moveMuon(..),
0167       //  also check that we do not have any mistyping like 'deformations' or 'deformation2'
0168       const auto lastCharacter = (iParam->empty() ? '_' : (*iParam)[iParam->size() - 1]);
0169       if ((lastCharacter != 's' && !isdigit(lastCharacter) && (*iParam) != "Muon") ||
0170           iParam->find("deformation") != std::string::npos) {
0171         throw cms::Exception("BadConfig") << "@SUB=AlignableModifier::modify(..):\n"
0172                                           << "I see parameter '" << *iParam << "' of type PSet, "
0173                                           << "but expect either 'deformation' or a level name "
0174                                           << "with 's' or a digit at the end.\n";
0175       }  // other PSets should now be hierarchy levels and thus be OK to ignore here
0176     } else {
0177       if (!error.str().length())
0178         error << "Unknown parameter name(s): ";
0179       error << " " << *iParam;
0180     }
0181   }
0182 
0183   // Check if both 'localN' and 'phiNlocal' have been used
0184   if (rotX_ == 2)
0185     throw cms::Exception("BadConfig") << "Found both localX and phiXlocal";
0186   if (rotY_ == 2)
0187     throw cms::Exception("BadConfig") << "Found both localY and phiYlocal";
0188   if (rotZ_ == 2)
0189     throw cms::Exception("BadConfig") << "Found both localZ and phiZlocal";
0190 
0191   // Check error
0192   if (error.str().length())
0193     throw cms::Exception("BadConfig") << error.str();
0194 
0195   // Decode distribution
0196   this->setDistribution(distribution_);
0197 
0198   //if (scale_) { NO! Different random sequence if only parts scale to zero!
0199 
0200   // Apply displacements
0201   if (std::abs(dX_) + std::abs(dY_) + std::abs(dZ_) > 0 && setTranslations_)
0202     this->moveAlignable(alignable, random_, gaussian_, scale_ * dX_, scale_ * dY_, scale_ * dZ_);
0203 
0204   // Apply local displacements
0205   if (std::abs(dXlocal_) + std::abs(dYlocal_) + std::abs(dZlocal_) > 0 && setTranslations_)
0206     this->moveAlignableLocal(alignable, random_, gaussian_, scale_ * dXlocal_, scale_ * dYlocal_, scale_ * dZlocal_);
0207 
0208   // Apply rotations
0209   if (std::abs(phiX_) + std::abs(phiY_) + std::abs(phiZ_) > 0 && setRotations_)
0210     this->rotateAlignable(alignable, random_, gaussian_, scale_ * phiX_, scale_ * phiY_, scale_ * phiZ_);
0211 
0212   // Apply local rotations
0213   if (std::abs(phiXlocal_) + std::abs(phiYlocal_) + std::abs(phiZlocal_) > 0 && setRotations_)
0214     this->rotateAlignableLocal(
0215         alignable, random_, gaussian_, scale_ * phiXlocal_, scale_ * phiYlocal_, scale_ * phiZlocal_);
0216 
0217   // Apply twist
0218   if (std::abs(twist_) > 0)
0219     edm::LogError("NotImplemented") << "Twist is not implemented yet";
0220 
0221   // Apply shear
0222   if (std::abs(shear_) > 0)
0223     edm::LogError("NotImplemented") << "Shear is not implemented yet";
0224 
0225   if (!deformation_.first.empty()) {
0226     this->addDeformation(alignable, deformation_, random_, gaussian_, scale_);
0227   }
0228 
0229   // Apply error - first add scale_ to error
0230   scaleError_ *= scale_;
0231   if (setError_ && scaleError_) {
0232     // Alignment Position Error for flat distribution: 1 sigma
0233     if (!gaussian_)
0234       scaleError_ *= 0.68;
0235 
0236     // Error on displacement
0237     if (std::abs(dX_) + std::abs(dY_) + std::abs(dZ_) > 0 && setTranslations_)
0238       this->addAlignmentPositionError(alignable, scaleError_ * dX_, scaleError_ * dY_, scaleError_ * dZ_);
0239 
0240     // Error on local displacements
0241     if (std::abs(dXlocal_) + std::abs(dYlocal_) + std::abs(dZlocal_) > 0 && setTranslations_)
0242       this->addAlignmentPositionErrorLocal(
0243           alignable, scaleError_ * dXlocal_, scaleError_ * dYlocal_, scaleError_ * dZlocal_);
0244 
0245     // Error on rotations
0246     if (std::abs(phiX_) + std::abs(phiY_) + std::abs(phiZ_) > 0 && setRotations_)
0247       this->addAlignmentPositionErrorFromRotation(
0248           alignable, scaleError_ * phiX_, scaleError_ * phiY_, scaleError_ * phiZ_);
0249 
0250     // Error on local rotations
0251     if (std::abs(phiXlocal_) + std::abs(phiYlocal_) + std::abs(phiZlocal_) > 0 && setRotations_)
0252       this->addAlignmentPositionErrorFromLocalRotation(
0253           alignable, scaleError_ * phiXlocal_, scaleError_ * phiYlocal_, scaleError_ * phiZlocal_);
0254     // Do we need to add any APE for deformations?
0255     // Probably we would do so if there wouldn't be data, but only MC to play with... ;-)
0256   }
0257   // } // end if (scale_)
0258 
0259   return (m_modified > 0);
0260 }
0261 
0262 //__________________________________________________________________________________________________
0263 void AlignableModifier::setDistribution(const std::string& distr) {
0264   if (distr == "fixed")
0265     random_ = false;
0266   else if (distr == "flat") {
0267     random_ = true;
0268     gaussian_ = false;
0269   } else if (distr == "gaussian") {
0270     random_ = true;
0271     gaussian_ = true;
0272   }
0273 }
0274 
0275 //__________________________________________________________________________________________________
0276 /// If 'seed' is zero, asks  RandomNumberGenerator service.
0277 void AlignableModifier::setSeed(const long seed) {
0278   long m_seed;
0279 
0280   if (seed > 0)
0281     m_seed = seed;
0282   else {
0283     edm::Service<edm::RandomNumberGenerator> rng;
0284     m_seed = rng->mySeed();
0285   }
0286 
0287   LogDebug("PrintArgs") << "Setting generator seed to " << m_seed;
0288 
0289   theDRand48Engine->setSeed(m_seed);
0290 }
0291 
0292 //__________________________________________________________________________________________________
0293 /// If 'random' is false, the given movements are strictly applied. Otherwise, a random
0294 /// number is generated according to a gaussian or a flat distribution depending on 'gaussian'.
0295 void AlignableModifier::moveAlignable(
0296     Alignable* alignable, bool random, bool gaussian, float sigmaX, float sigmaY, float sigmaZ) {
0297   std::ostringstream message;
0298 
0299   // Get movement vector according to arguments
0300   GlobalVector moveV(sigmaX, sigmaY, sigmaZ);  // Default: fixed
0301   if (random) {
0302     std::vector<float> randomNumbers;
0303     message << "random ";
0304     if (gaussian) {
0305       randomNumbers = this->gaussianRandomVector(sigmaX, sigmaY, sigmaZ);
0306       message << "gaussian ";
0307     } else {
0308       randomNumbers = this->flatRandomVector(sigmaX, sigmaY, sigmaZ);
0309       message << "flat ";
0310     }
0311     moveV = GlobalVector(randomNumbers[0], randomNumbers[1], randomNumbers[2]);
0312   }
0313 
0314   message << " move with sigma " << sigmaX << " " << sigmaY << " " << sigmaZ;
0315 
0316   LogDebug("PrintArgs") << message.str();  // Arguments
0317 
0318   LogDebug("PrintMovement") << "applied displacement: " << moveV;  // Actual movements
0319   alignable->move(moveV);
0320   m_modified++;
0321 }
0322 
0323 //__________________________________________________________________________________________________
0324 /// If 'random' is false, the given movements are strictly applied. Otherwise, a random
0325 /// number is generated according to a gaussian or a flat distribution depending on 'gaussian'.
0326 void AlignableModifier::moveAlignableLocal(
0327     Alignable* alignable, bool random, bool gaussian, float sigmaX, float sigmaY, float sigmaZ) {
0328   std::ostringstream message;
0329 
0330   // Get movement vector according to arguments
0331   align::LocalVector moveV(sigmaX, sigmaY, sigmaZ);  // Default: fixed
0332   if (random) {
0333     std::vector<float> randomNumbers;
0334     message << "random ";
0335     if (gaussian) {
0336       randomNumbers = this->gaussianRandomVector(sigmaX, sigmaY, sigmaZ);
0337       message << "gaussian ";
0338     } else {
0339       randomNumbers = this->flatRandomVector(sigmaX, sigmaY, sigmaZ);
0340       message << "flat ";
0341     }
0342     moveV = align::LocalVector(randomNumbers[0], randomNumbers[1], randomNumbers[2]);
0343   }
0344 
0345   message << " move with sigma " << sigmaX << " " << sigmaY << " " << sigmaZ;
0346 
0347   LogDebug("PrintArgs") << message.str();  // Arguments
0348 
0349   LogDebug("PrintMovement") << "applied local displacement: " << moveV;  // Actual movements
0350   alignable->move(alignable->surface().toGlobal(moveV));
0351   m_modified++;
0352 }
0353 
0354 //__________________________________________________________________________________________________
0355 void AlignableModifier ::addDeformation(Alignable* alignable,
0356                                         const AlignableModifier::DeformationMemberType& deformation,
0357                                         bool random,
0358                                         bool gaussian,
0359                                         double scale) {
0360   const SurfaceDeformationFactory::Type deformType =
0361       SurfaceDeformationFactory::surfaceDeformationType(deformation.first);
0362 
0363   // Scale and randomize
0364   // (need a little hack since ySplit must not be treated)!
0365   const bool rndNotLast = (deformType == SurfaceDeformationFactory::kTwoBowedSurfaces);
0366   std::vector<double> rndDeformation(deformation.second.begin(), deformation.second.end() - (rndNotLast ? 1 : 0));
0367   for (unsigned int i = 0; i < rndDeformation.size(); ++i) {
0368     rndDeformation[i] *= scale;
0369   }
0370   if (random) {
0371     this->randomise(rndDeformation, gaussian);
0372   }
0373   if (rndNotLast) {  // put back ySplit at the end
0374     rndDeformation.push_back(deformation.second.back());
0375   }
0376 
0377   // auto_ptr has exception safe delete (in contrast to bare pointer)
0378   const std::unique_ptr<SurfaceDeformation> surfDef(SurfaceDeformationFactory::create(deformType, rndDeformation));
0379 
0380   alignable->addSurfaceDeformation(surfDef.get(), true);  // true to propagate down
0381   ++m_modified;
0382 }
0383 
0384 //__________________________________________________________________________________________________
0385 /// If 'random' is false, the given rotations are strictly applied. Otherwise, a random
0386 /// number is generated according to a gaussian or a flat distribution depending on 'gaussian'.
0387 void AlignableModifier::rotateAlignable(
0388     Alignable* alignable, bool random, bool gaussian, float sigmaPhiX, float sigmaPhiY, float sigmaPhiZ) {
0389   std::ostringstream message;
0390 
0391   // Get rotation vector according to arguments
0392   GlobalVector rotV(sigmaPhiX, sigmaPhiY, sigmaPhiZ);  // Default: fixed
0393   if (random) {
0394     std::vector<float> randomNumbers;
0395     message << "random ";
0396     if (gaussian) {
0397       randomNumbers = this->gaussianRandomVector(sigmaPhiX, sigmaPhiY, sigmaPhiZ);
0398       message << "gaussian ";
0399     } else {
0400       randomNumbers = flatRandomVector(sigmaPhiX, sigmaPhiY, sigmaPhiZ);
0401       message << "flat ";
0402     }
0403     rotV = GlobalVector(randomNumbers[0], randomNumbers[1], randomNumbers[2]);
0404   }
0405 
0406   message << "global rotation by angles " << sigmaPhiX << " " << sigmaPhiY << " " << sigmaPhiZ;
0407 
0408   LogDebug("PrintArgs") << message.str();  // Arguments
0409 
0410   LogDebug("PrintMovement") << "applied rotation angles: " << rotV;  // Actual movements
0411   if (std::abs(sigmaPhiX))
0412     alignable->rotateAroundGlobalX(rotV.x());
0413   if (std::abs(sigmaPhiY))
0414     alignable->rotateAroundGlobalY(rotV.y());
0415   if (std::abs(sigmaPhiZ))
0416     alignable->rotateAroundGlobalZ(rotV.z());
0417   m_modified++;
0418 }
0419 
0420 //__________________________________________________________________________________________________
0421 /// If 'random' is false, the given rotations are strictly applied. Otherwise, a random
0422 /// number is generated according to a gaussian or a flat distribution depending on 'gaussian'.
0423 void AlignableModifier::rotateAlignableLocal(
0424     Alignable* alignable, bool random, bool gaussian, float sigmaPhiX, float sigmaPhiY, float sigmaPhiZ) {
0425   std::ostringstream message;
0426 
0427   // Get rotation vector according to arguments
0428   align::LocalVector rotV(sigmaPhiX, sigmaPhiY, sigmaPhiZ);  // Default: fixed
0429   if (random) {
0430     std::vector<float> randomNumbers;
0431     message << "random ";
0432     if (gaussian) {
0433       randomNumbers = this->gaussianRandomVector(sigmaPhiX, sigmaPhiY, sigmaPhiZ);
0434       message << "gaussian ";
0435     } else {
0436       randomNumbers = flatRandomVector(sigmaPhiX, sigmaPhiY, sigmaPhiZ);
0437       message << "flat ";
0438     }
0439     rotV = align::LocalVector(randomNumbers[0], randomNumbers[1], randomNumbers[2]);
0440   }
0441 
0442   message << "local rotation by angles " << sigmaPhiX << " " << sigmaPhiY << " " << sigmaPhiZ;
0443 
0444   LogDebug("PrintArgs") << message.str();  // Arguments
0445 
0446   LogDebug("PrintMovement") << "applied local rotation angles: " << rotV;  // Actual movements
0447   if (std::abs(sigmaPhiX))
0448     alignable->rotateAroundLocalX(rotV.x());
0449   if (std::abs(sigmaPhiY))
0450     alignable->rotateAroundLocalY(rotV.y());
0451   if (std::abs(sigmaPhiZ))
0452     alignable->rotateAroundLocalZ(rotV.z());
0453   m_modified++;
0454 }
0455 
0456 //__________________________________________________________________________________________________
0457 const std::vector<float> AlignableModifier::gaussianRandomVector(float sigmaX, float sigmaY, float sigmaZ) const {
0458   // Get absolute value if negative arguments
0459   if (sigmaX < 0) {
0460     edm::LogWarning("BadConfig") << " taking absolute value for gaussian sigma_x";
0461     sigmaX = std::abs(sigmaX);
0462   }
0463   if (sigmaY < 0) {
0464     edm::LogWarning("BadConfig") << " taking absolute value for gaussian sigma_y";
0465     sigmaY = std::abs(sigmaY);
0466   }
0467   if (sigmaZ < 0) {
0468     edm::LogWarning("BadConfig") << " taking absolute value for gaussian sigma_z";
0469     sigmaZ = std::abs(sigmaZ);
0470   }
0471 
0472   // Pass by reference, otherwise pointer is deleted!
0473   CLHEP::RandGauss aGaussObjX(*theDRand48Engine, 0., sigmaX);
0474   CLHEP::RandGauss aGaussObjY(*theDRand48Engine, 0., sigmaY);
0475   CLHEP::RandGauss aGaussObjZ(*theDRand48Engine, 0., sigmaZ);
0476 
0477   std::vector<float> randomVector;
0478   randomVector.push_back(aGaussObjX.fire());
0479   randomVector.push_back(aGaussObjY.fire());
0480   randomVector.push_back(aGaussObjZ.fire());
0481 
0482   return randomVector;
0483 }
0484 
0485 //__________________________________________________________________________________________________
0486 const std::vector<float> AlignableModifier::flatRandomVector(float sigmaX, float sigmaY, float sigmaZ) const {
0487   // Get absolute value if negative arguments
0488   if (sigmaX < 0) {
0489     edm::LogWarning("BadConfig") << " taking absolute value for flat sigma_x";
0490     sigmaX = std::abs(sigmaX);
0491   }
0492   if (sigmaY < 0) {
0493     edm::LogWarning("BadConfig") << " taking absolute value for flat sigma_y";
0494     sigmaY = std::abs(sigmaY);
0495   }
0496   if (sigmaZ < 0) {
0497     edm::LogWarning("BadConfig") << " taking absolute value for flat sigma_z";
0498     sigmaZ = std::abs(sigmaZ);
0499   }
0500 
0501   CLHEP::RandFlat aFlatObjX(*theDRand48Engine, -sigmaX, sigmaX);
0502   CLHEP::RandFlat aFlatObjY(*theDRand48Engine, -sigmaY, sigmaY);
0503   CLHEP::RandFlat aFlatObjZ(*theDRand48Engine, -sigmaZ, sigmaZ);
0504 
0505   std::vector<float> randomVector;
0506   randomVector.push_back(aFlatObjX.fire());
0507   randomVector.push_back(aFlatObjY.fire());
0508   randomVector.push_back(aFlatObjZ.fire());
0509 
0510   return randomVector;
0511 }
0512 
0513 //__________________________________________________________________________________________________
0514 void AlignableModifier::randomise(std::vector<double>& rnd, bool gaussian) const {
0515   for (unsigned int i = 0; i < rnd.size(); ++i) {
0516     if (rnd[i] < 0.) {
0517       edm::LogWarning("BadConfig") << " taking absolute value to randomise " << i;
0518       rnd[i] = std::abs(rnd[i]);
0519     }
0520 
0521     if (gaussian) {
0522       CLHEP::RandGauss aGaussObj(*theDRand48Engine, 0., rnd[i]);
0523       rnd[i] = aGaussObj.fire();
0524     } else {
0525       CLHEP::RandFlat aFlatObj(*theDRand48Engine, -rnd[i], rnd[i]);
0526       rnd[i] = aFlatObj.fire();
0527     }
0528   }
0529 }
0530 
0531 //__________________________________________________________________________________________________
0532 void AlignableModifier::addAlignmentPositionError(Alignable* alignable, float dx, float dy, float dz) {
0533   LogDebug("PrintArgs") << "Adding an AlignmentPositionError of size " << dx << " " << dy << " " << dz;
0534 
0535   AlignmentPositionError ape(dx, dy, dz);
0536   alignable->addAlignmentPositionError(ape, true);
0537 }
0538 
0539 //__________________________________________________________________________________________________
0540 void AlignableModifier::addAlignmentPositionErrorLocal(Alignable* alignable, float dx, float dy, float dz) {
0541   LogDebug("PrintArgs") << "Adding a local AlignmentPositionError of size " << dx << " " << dy << " " << dz;
0542 
0543   AlgebraicSymMatrix as(3, 0);  //3x3, zeroed
0544   as[0][0] = dx * dx;
0545   as[1][1] = dy * dy;
0546   as[2][2] = dz * dz;                                    //diagonals
0547   align::RotationType rt = alignable->globalRotation();  //get rotation
0548   AlgebraicMatrix am(3, 3);
0549   am[0][0] = rt.xx();
0550   am[0][1] = rt.xy();
0551   am[0][2] = rt.xz();
0552   am[1][0] = rt.yx();
0553   am[1][1] = rt.yy();
0554   am[1][2] = rt.yz();
0555   am[2][0] = rt.zx();
0556   am[2][1] = rt.zy();
0557   am[2][2] = rt.zz();
0558   as = as.similarityT(am);  //rotate error matrix
0559 
0560   GlobalError ge(asSMatrix<3>(as));
0561   GlobalErrorExtended gee(ge.cxx(),
0562                           ge.cyx(),
0563                           ge.czx(),
0564                           0.,
0565                           0.,
0566                           0.,
0567                           ge.cyy(),
0568                           ge.czy(),
0569                           0.,
0570                           0.,
0571                           0.,
0572                           ge.czz(),
0573                           0.,
0574                           0.,
0575                           0.,
0576                           0.,
0577                           0.,
0578                           0.,
0579                           0.,
0580                           0.,
0581                           0.);
0582   AlignmentPositionError ape(gee);
0583 
0584   alignable->addAlignmentPositionError(ape, true);  // propagate down to components
0585 }
0586 
0587 //__________________________________________________________________________________________________
0588 void AlignableModifier::addAlignmentPositionErrorFromRotation(Alignable* alignable, float phiX, float phiY, float phiZ) {
0589   align::RotationType rotx(Basic3DVector<float>(1.0, 0.0, 0.0), phiX);
0590   align::RotationType roty(Basic3DVector<float>(0.0, 1.0, 0.0), phiY);
0591   align::RotationType rotz(Basic3DVector<float>(0.0, 0.0, 1.0), phiZ);
0592   align::RotationType rot = rotz * roty * rotx;
0593 
0594   this->addAlignmentPositionErrorFromRotation(alignable, rot);
0595 }
0596 
0597 //__________________________________________________________________________________________________
0598 void AlignableModifier::addAlignmentPositionErrorFromLocalRotation(Alignable* alignable,
0599                                                                    float phiX,
0600                                                                    float phiY,
0601                                                                    float phiZ) {
0602   align::RotationType rotx(Basic3DVector<float>(1.0, 0.0, 0.0), phiX);
0603   align::RotationType roty(Basic3DVector<float>(0.0, 1.0, 0.0), phiY);
0604   align::RotationType rotz(Basic3DVector<float>(0.0, 0.0, 1.0), phiZ);
0605   align::RotationType rot = rotz * roty * rotx;
0606 
0607   this->addAlignmentPositionErrorFromLocalRotation(alignable, rot);
0608 }
0609 
0610 //__________________________________________________________________________________________________
0611 void AlignableModifier::addAlignmentPositionErrorFromRotation(Alignable* alignable, align::RotationType& rotation) {
0612   LogDebug("PrintArgs") << "Adding an AlignmentPositionError from Rotation" << std::endl << rotation;
0613 
0614   alignable->addAlignmentPositionErrorFromRotation(rotation, true);  // propagate down to components
0615 }
0616 
0617 //__________________________________________________________________________________________________
0618 void AlignableModifier::addAlignmentPositionErrorFromLocalRotation(Alignable* alignable,
0619                                                                    align::RotationType& rotation) {
0620   LogDebug("PrintArgs") << "Adding an AlignmentPositionError from Local Rotation" << std::endl << rotation;
0621 
0622   // true: propagate down to components
0623   alignable->addAlignmentPositionErrorFromLocalRotation(rotation, true);
0624 }