00001 #include "CLHEP/Random/DRand48Engine.h"
00002 #include "CLHEP/Random/RandGauss.h"
00003 #include "CLHEP/Random/Randomize.h"
00004
00005 #include "DataFormats/TrackingRecHit/interface/AlignmentPositionError.h"
00006 #include "FWCore/ServiceRegistry/interface/Service.h"
00007 #include "FWCore/Utilities/interface/RandomNumberGenerator.h"
00008 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00009 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00010
00011 #include "Alignment/CommonAlignment/interface/AlignableComposite.h"
00012 #include "Alignment/CommonAlignment/interface/AlignableModifier.h"
00013
00014
00015
00016 AlignableModifier::AlignableModifier( void )
00017 {
00018
00019 theDRand48Engine = new DRand48Engine();
00020
00021 }
00022
00023
00024
00025 AlignableModifier::~AlignableModifier()
00026 {
00027
00028 delete theDRand48Engine;
00029
00030 }
00031
00032
00033 void AlignableModifier::init_( void )
00034 {
00035
00036
00037 distribution_ = "";
00038 setError_ = false;
00039 setRotations_ = true;
00040 setTranslations_ = true;
00041 scale_ = 1.;
00042 scaleError_ = 1.;
00043 phiX_ = 0.;
00044 phiY_ = 0.;
00045 phiZ_ = 0.;
00046 phiXlocal_ = 0.;
00047 phiYlocal_ = 0.;
00048 phiZlocal_ = 0.;
00049 dX_ = 0.;
00050 dY_ = 0.;
00051 dZ_ = 0.;
00052 dXlocal_ = 0.;
00053 dYlocal_ = 0.;
00054 dZlocal_ = 0.;
00055 twist_ = 0.;
00056 shear_ = 0.;
00057
00058
00059 random_ = true;
00060 gaussian_ = true;
00061
00062 }
00063
00064
00065
00066 const bool AlignableModifier::isPropagated( const std::string& parameterName ) const
00067 {
00068
00069 if ( parameterName == "distribution" ||
00070 parameterName == "setError" ||
00071 parameterName == "scaleError" ||
00072 parameterName == "setRotations" ||
00073 parameterName == "setTranslations" ||
00074 parameterName == "scale"
00075 ) return true;
00076
00077 return false;
00078
00079 }
00080
00081
00082
00084 bool AlignableModifier::modify( Alignable* alignable, const edm::ParameterSet& pSet )
00085 {
00086
00087
00088 this->init_();
00089 int rotX_=0, rotY_=0, rotZ_=0;
00090
00091
00092
00093 m_modified = 0;
00094
00095
00096 std::ostringstream error;
00097 std::vector<std::string> parameterNames = pSet.getParameterNames();
00098 for ( std::vector<std::string>::iterator iParam = parameterNames.begin();
00099 iParam != parameterNames.end(); iParam++ ) {
00100 if ( (*iParam) == "distribution" ) distribution_ = pSet.getParameter<std::string>( *iParam );
00101 else if ( (*iParam) == "setError" ) setError_ = pSet.getParameter<bool>( *iParam );
00102 else if ( (*iParam) == "setRotations") setRotations_ = pSet.getParameter<bool>( *iParam );
00103 else if ( (*iParam) == "setTranslations") setTranslations_ = pSet.getParameter<bool>( *iParam );
00104 else if ( (*iParam) == "scale" ) scale_ = pSet.getParameter<double>( *iParam );
00105 else if ( (*iParam) == "scaleError" ) scaleError_ = pSet.getParameter<double>( *iParam );
00106 else if ( (*iParam) == "phiX" ) phiX_ = pSet.getParameter<double>( *iParam );
00107 else if ( (*iParam) == "phiY" ) phiY_ = pSet.getParameter<double>( *iParam );
00108 else if ( (*iParam) == "phiZ" ) phiZ_ = pSet.getParameter<double>( *iParam );
00109 else if ( (*iParam) == "dX" ) dX_ = pSet.getParameter<double>( *iParam );
00110 else if ( (*iParam) == "dY" ) dY_ = pSet.getParameter<double>( *iParam );
00111 else if ( (*iParam) == "dZ" ) dZ_ = pSet.getParameter<double>( *iParam );
00112 else if ( (*iParam) == "dXlocal" ) dXlocal_ = pSet.getParameter<double>( *iParam );
00113 else if ( (*iParam) == "dYlocal" ) dYlocal_ = pSet.getParameter<double>( *iParam );
00114 else if ( (*iParam) == "dZlocal" ) dZlocal_ = pSet.getParameter<double>( *iParam );
00115 else if ( (*iParam) == "twist" ) twist_ = pSet.getParameter<double>( *iParam );
00116 else if ( (*iParam) == "shear" ) shear_ = pSet.getParameter<double>( *iParam );
00117 else if ( (*iParam) == "localX" ) { phiXlocal_=pSet.getParameter<double>( *iParam ); rotX_++; }
00118 else if ( (*iParam) == "localY" ) { phiYlocal_=pSet.getParameter<double>( *iParam ); rotY_++; }
00119 else if ( (*iParam) == "localZ" ) { phiZlocal_=pSet.getParameter<double>( *iParam ); rotZ_++; }
00120 else if ( (*iParam) == "phiXlocal" ) { phiXlocal_=pSet.getParameter<double>( *iParam ); rotX_++; }
00121 else if ( (*iParam) == "phiYlocal" ) { phiYlocal_=pSet.getParameter<double>( *iParam ); rotY_++; }
00122 else if ( (*iParam) == "phiZlocal" ) { phiZlocal_=pSet.getParameter<double>( *iParam ); rotZ_++; }
00123 else if ( pSet.retrieve( *iParam ).typeCode() != 'P' ) {
00124 if ( !error.str().length() ) error << "Unknown parameter name(s): ";
00125 error << " " << *iParam;
00126 }
00127 }
00128
00129
00130 if ( rotX_==2 ) throw cms::Exception("BadConfig") << "Found both localX and phiXlocal";
00131 if ( rotY_==2 ) throw cms::Exception("BadConfig") << "Found both localY and phiYlocal";
00132 if ( rotZ_==2 ) throw cms::Exception("BadConfig") << "Found both localZ and phiZlocal";
00133
00134
00135 if ( error.str().length() )
00136 throw cms::Exception("BadConfig") << error.str();
00137
00138
00139 this->setDistribution( distribution_ );
00140
00141
00142 if ( std::abs(dX_) + std::abs(dY_) + std::abs(dZ_) > 0 && setTranslations_ )
00143 this->moveAlignable( alignable, random_, gaussian_, scale_*dX_, scale_*dY_, scale_*dZ_ );
00144
00145
00146 if ( std::abs(dXlocal_) + std::abs(dYlocal_) + std::abs(dZlocal_) > 0 && setTranslations_ )
00147 this->moveAlignableLocal( alignable, random_, gaussian_,
00148 scale_*dXlocal_, scale_*dYlocal_, scale_*dZlocal_ );
00149
00150
00151 if ( std::abs(phiX_) + std::abs(phiY_) + std::abs(phiZ_) > 0 && setRotations_ )
00152 this->rotateAlignable( alignable, random_, gaussian_, scale_*phiX_, scale_*phiY_, scale_*phiZ_ );
00153
00154
00155 if ( std::abs(phiXlocal_) + std::abs(phiYlocal_) + std::abs(phiZlocal_) > 0 && setRotations_ )
00156 this->rotateAlignableLocal( alignable, random_, gaussian_,
00157 scale_*phiXlocal_, scale_*phiYlocal_, scale_*phiZlocal_ );
00158
00159
00160 if ( std::abs(twist_) > 0 )
00161 edm::LogError("NotImplemented") << "Twist is not implemented yet";
00162
00163
00164 if ( std::abs(shear_) > 0 )
00165 edm::LogError("NotImplemented") << "Shear is not implemented yet";
00166
00167
00168 if ( setError_ ) {
00169
00170 if ( !gaussian_ ) scaleError_ *= 0.68;
00171
00172
00173 scaleError_ *= scale_;
00174
00175
00176 if ( std::abs(dX_) + std::abs(dY_) + std::abs(dZ_) > 0 && setTranslations_ )
00177 this->addAlignmentPositionError( alignable,
00178 scaleError_*dX_, scaleError_*dY_, scaleError_*dZ_ );
00179
00180
00181 if ( std::abs(dXlocal_) + std::abs(dYlocal_) + std::abs(dZlocal_) > 0 && setTranslations_ )
00182 this->addAlignmentPositionErrorLocal( alignable,
00183 scaleError_*dXlocal_, scaleError_*dYlocal_,
00184 scaleError_*dZlocal_ );
00185
00186
00187 if ( std::abs(phiX_) + std::abs(phiY_) + std::abs(phiZ_) > 0 && setRotations_ )
00188 this->addAlignmentPositionErrorFromRotation( alignable,
00189 scaleError_*phiX_, scaleError_*phiY_,
00190 scaleError_*phiZ_ );
00191
00192
00193 if ( std::abs(phiXlocal_) + std::abs(phiYlocal_) + std::abs(phiZlocal_) > 0 && setRotations_ )
00194 this->addAlignmentPositionErrorFromLocalRotation( alignable,
00195 scaleError_*phiXlocal_,
00196 scaleError_*phiYlocal_,
00197 scaleError_*phiZlocal_ );
00198 }
00199
00200 return ( m_modified > 0 );
00201
00202 }
00203
00204
00205
00206 void AlignableModifier::setDistribution( const std::string& distr )
00207 {
00208
00209 if ( distr == "fixed" ) random_ = false;
00210 else if ( distr == "flat" ) {
00211 random_ = true;
00212 gaussian_ = false;
00213 } else if ( distr == "gaussian" ) {
00214 random_ = true;
00215 gaussian_ = true;
00216 }
00217
00218 }
00219
00220
00221
00223 void AlignableModifier::setSeed( const long seed )
00224 {
00225
00226 long m_seed;
00227
00228 if ( seed > 0 ) m_seed = seed;
00229 else {
00230 edm::Service<edm::RandomNumberGenerator> rng;
00231 m_seed = rng->mySeed();
00232 }
00233
00234 LogDebug("PrintArgs") << "Setting generator seed to " << m_seed;
00235
00236 theDRand48Engine->setSeed( m_seed );
00237
00238 }
00239
00240
00243 void AlignableModifier::moveAlignable( Alignable* alignable, bool random, bool gaussian,
00244 float sigmaX, float sigmaY, float sigmaZ )
00245 {
00246
00247
00248 std::ostringstream message;
00249
00250
00251 GlobalVector moveV( sigmaX, sigmaY, sigmaZ );
00252 if ( random ) {
00253 std::vector<float> randomNumbers;
00254 message << "random ";
00255 if (gaussian) {
00256 randomNumbers = this->gaussianRandomVector( sigmaX, sigmaY, sigmaZ );
00257 message << "gaussian ";
00258 } else {
00259 randomNumbers = this->flatRandomVector( sigmaX, sigmaY, sigmaZ );
00260 message << "flat ";
00261 }
00262 moveV = GlobalVector( randomNumbers[0], randomNumbers[1], randomNumbers[2] );
00263 }
00264
00265 message << " move with sigma " << sigmaX << " " << sigmaY << " " << sigmaZ;
00266
00267 LogDebug("PrintArgs") << message.str();
00268
00269 LogDebug("PrintMovement") << "applied displacement: " << moveV;
00270 alignable->move(moveV);
00271 m_modified++;
00272
00273
00274 }
00275
00276
00279 void AlignableModifier::moveAlignableLocal( Alignable* alignable, bool random, bool gaussian,
00280 float sigmaX, float sigmaY, float sigmaZ )
00281 {
00282
00283
00284 std::ostringstream message;
00285
00286
00287 align::LocalVector moveV( sigmaX, sigmaY, sigmaZ );
00288 if ( random ) {
00289 std::vector<float> randomNumbers;
00290 message << "random ";
00291 if (gaussian) {
00292 randomNumbers = this->gaussianRandomVector( sigmaX, sigmaY, sigmaZ );
00293 message << "gaussian ";
00294 } else {
00295 randomNumbers = this->flatRandomVector( sigmaX, sigmaY, sigmaZ );
00296 message << "flat ";
00297 }
00298 moveV = align::LocalVector( randomNumbers[0], randomNumbers[1], randomNumbers[2] );
00299 }
00300
00301 message << " move with sigma " << sigmaX << " " << sigmaY << " " << sigmaZ;
00302
00303 LogDebug("PrintArgs") << message.str();
00304
00305 LogDebug("PrintMovement") << "applied local displacement: " << moveV;
00306 alignable->move( alignable->surface().toGlobal(moveV) );
00307 m_modified++;
00308
00309
00310 }
00311
00312
00313
00316 void AlignableModifier::rotateAlignable( Alignable* alignable, bool random, bool gaussian,
00317 float sigmaPhiX, float sigmaPhiY, float sigmaPhiZ )
00318 {
00319
00320
00321 std::ostringstream message;
00322
00323
00324 GlobalVector rotV( sigmaPhiX, sigmaPhiY, sigmaPhiZ );
00325 if ( random ) {
00326 std::vector<float> randomNumbers;
00327 message << "random ";
00328 if (gaussian) {
00329 randomNumbers = this->gaussianRandomVector( sigmaPhiX, sigmaPhiY, sigmaPhiZ );
00330 message << "gaussian ";
00331 } else {
00332 randomNumbers = flatRandomVector( sigmaPhiX, sigmaPhiY, sigmaPhiZ );
00333 message << "flat ";
00334 }
00335 rotV = GlobalVector( randomNumbers[0], randomNumbers[1], randomNumbers[2] );
00336 }
00337
00338 message << "global rotation by angles " << sigmaPhiX << " " << sigmaPhiY << " " << sigmaPhiZ;
00339
00340 LogDebug("PrintArgs") << message.str();
00341
00342 LogDebug("PrintMovement") << "applied rotation angles: " << rotV;
00343 if ( std::abs(sigmaPhiX) ) alignable->rotateAroundGlobalX( rotV.x() );
00344 if ( std::abs(sigmaPhiY) ) alignable->rotateAroundGlobalY( rotV.y() );
00345 if ( std::abs(sigmaPhiZ) ) alignable->rotateAroundGlobalZ( rotV.z() );
00346 m_modified++;
00347
00348
00349 }
00350
00351
00354 void
00355 AlignableModifier::rotateAlignableLocal( Alignable* alignable, bool random, bool gaussian,
00356 float sigmaPhiX, float sigmaPhiY, float sigmaPhiZ )
00357 {
00358
00359
00360 std::ostringstream message;
00361
00362
00363 align::LocalVector rotV( sigmaPhiX, sigmaPhiY, sigmaPhiZ );
00364 if ( random ) {
00365 std::vector<float> randomNumbers;
00366 message << "random ";
00367 if (gaussian) {
00368 randomNumbers = this->gaussianRandomVector( sigmaPhiX, sigmaPhiY, sigmaPhiZ );
00369 message << "gaussian ";
00370 } else {
00371 randomNumbers = flatRandomVector( sigmaPhiX, sigmaPhiY, sigmaPhiZ );
00372 message << "flat ";
00373 }
00374 rotV = align::LocalVector( randomNumbers[0], randomNumbers[1], randomNumbers[2] );
00375 }
00376
00377 message << "local rotation by angles " << sigmaPhiX << " " << sigmaPhiY << " " << sigmaPhiZ;
00378
00379 LogDebug("PrintArgs") << message.str();
00380
00381 LogDebug("PrintMovement") << "applied local rotation angles: " << rotV;
00382 if ( std::abs(sigmaPhiX) ) alignable->rotateAroundLocalX( rotV.x() );
00383 if ( std::abs(sigmaPhiY) ) alignable->rotateAroundLocalY( rotV.y() );
00384 if ( std::abs(sigmaPhiZ) ) alignable->rotateAroundLocalZ( rotV.z() );
00385 m_modified++;
00386
00387
00388 }
00389
00390
00391
00392 const std::vector<float>
00393 AlignableModifier::gaussianRandomVector( float sigmaX, float sigmaY, float sigmaZ ) const
00394 {
00395
00396
00397 if ( sigmaX < 0 ) {
00398 edm::LogWarning("BadConfig") << " taking absolute value for gaussian sigma_x";
00399 sigmaX = std::abs(sigmaX);
00400 }
00401 if ( sigmaY < 0 ) {
00402 edm::LogWarning("BadConfig") << " taking absolute value for gaussian sigma_y";
00403 sigmaY = std::abs(sigmaY);
00404 }
00405 if ( sigmaZ < 0 ) {
00406 edm::LogWarning("BadConfig") << " taking absolute value for gaussian sigma_z";
00407 sigmaZ = std::abs(sigmaZ);
00408 }
00409
00410
00411 RandGauss aGaussObjX( *theDRand48Engine, 0., sigmaX );
00412 RandGauss aGaussObjY( *theDRand48Engine, 0., sigmaY );
00413 RandGauss aGaussObjZ( *theDRand48Engine, 0., sigmaZ );
00414
00415 std::vector<float> randomVector;
00416 randomVector.push_back( aGaussObjX.fire() );
00417 randomVector.push_back( aGaussObjY.fire() );
00418 randomVector.push_back( aGaussObjZ.fire() );
00419
00420 return randomVector;
00421
00422 }
00423
00424
00425
00426 const std::vector<float>
00427 AlignableModifier::flatRandomVector( float sigmaX,float sigmaY, float sigmaZ ) const
00428 {
00429
00430
00431 if ( sigmaX < 0 ) {
00432 edm::LogWarning("BadConfig") << " taking absolute value for gaussian sigma_x";
00433 sigmaX = std::abs(sigmaX);
00434 }
00435 if ( sigmaY < 0 ) {
00436 edm::LogWarning("BadConfig") << " taking absolute value for gaussian sigma_y";
00437 sigmaY = std::abs(sigmaY);
00438 }
00439 if ( sigmaZ < 0 ) {
00440 edm::LogWarning("BadConfig") << " taking absolute value for gaussian sigma_z";
00441 sigmaZ = std::abs(sigmaZ);
00442 }
00443
00444 RandFlat aFlatObjX( *theDRand48Engine, -sigmaX, sigmaX );
00445 RandFlat aFlatObjY( *theDRand48Engine, -sigmaY, sigmaY );
00446 RandFlat aFlatObjZ( *theDRand48Engine, -sigmaZ, sigmaZ );
00447
00448 std::vector<float> randomVector;
00449 randomVector.push_back( aFlatObjX.fire() );
00450 randomVector.push_back( aFlatObjY.fire() );
00451 randomVector.push_back( aFlatObjZ.fire() );
00452
00453 return randomVector;
00454
00455 }
00456
00457
00458
00459
00460 void AlignableModifier::addAlignmentPositionError( Alignable* alignable,
00461 float dx, float dy, float dz )
00462 {
00463
00464 LogDebug("PrintArgs") << "Adding an AlignmentPositionError of size "
00465 << dx << " " << dy << " " << dz;
00466
00467 AlignmentPositionError ape(dx,dy,dz);
00468 alignable->addAlignmentPositionError( ape );
00469
00470 }
00471
00472
00473
00474 void AlignableModifier::addAlignmentPositionErrorLocal( Alignable* alignable,
00475 float dx, float dy, float dz )
00476 {
00477
00478 LogDebug("PrintArgs") << "Adding a local AlignmentPositionError of size "
00479 << dx << " " << dy << " " << dz;
00480
00481 align::GlobalVector error = alignable->surface().toGlobal( align::LocalVector(dx,dy,dz) );
00482
00483 AlignmentPositionError ape( error.x(), error.y(), error.z() );
00484 alignable->addAlignmentPositionError( ape );
00485
00486 }
00487
00488
00489
00490
00491 void AlignableModifier::addAlignmentPositionErrorFromRotation( Alignable* alignable,
00492 float phiX, float phiY,
00493 float phiZ )
00494 {
00495
00496 align::RotationType rotx( Basic3DVector<float>(1.0, 0.0, 0.0), phiX );
00497 align::RotationType roty( Basic3DVector<float>(0.0, 1.0, 0.0), phiY );
00498 align::RotationType rotz( Basic3DVector<float>(0.0, 0.0, 1.0), phiZ );
00499 align::RotationType rot = rotz * roty * rotx;
00500
00501 this->addAlignmentPositionErrorFromRotation( alignable, rot );
00502
00503 }
00504
00505
00506
00507 void AlignableModifier::addAlignmentPositionErrorFromLocalRotation( Alignable* alignable,
00508 float phiX, float phiY,
00509 float phiZ )
00510 {
00511
00512 align::RotationType rotx( Basic3DVector<float>(1.0, 0.0, 0.0), phiX );
00513 align::RotationType roty( Basic3DVector<float>(0.0, 1.0, 0.0), phiY );
00514 align::RotationType rotz( Basic3DVector<float>(0.0, 0.0, 1.0), phiZ );
00515 align::RotationType rot = rotz * roty * rotx;
00516
00517 this->addAlignmentPositionErrorFromLocalRotation( alignable, rot );
00518
00519 }
00520
00521
00522
00523 void AlignableModifier::addAlignmentPositionErrorFromRotation( Alignable* alignable,
00524 align::RotationType& rotation )
00525 {
00526
00527 LogDebug("PrintArgs") << "Adding an AlignmentPositionError from Rotation" << std::endl
00528 << rotation;
00529
00530 alignable->addAlignmentPositionErrorFromRotation( rotation );
00531
00532 }
00533
00534
00535
00536 void AlignableModifier::addAlignmentPositionErrorFromLocalRotation( Alignable* alignable,
00537 align::RotationType& rotation )
00538 {
00539
00540 LogDebug("PrintArgs") << "Adding an AlignmentPositionError from Local Rotation" << std::endl
00541 << rotation;
00542
00543 alignable->addAlignmentPositionErrorFromLocalRotation( rotation );
00544
00545 }
00546