00001
00009 #include <string>
00010 #include <iostream>
00011 #include <sstream>
00012
00013
00014 #include "FWCore/Utilities/interface/Exception.h"
00015 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00016
00017
00018
00019 #include "Alignment/MuonAlignment/interface/MuonScenarioBuilder.h"
00020 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00021 #include "Alignment/CommonAlignment/interface/Alignable.h"
00022 #include "DataFormats/MuonDetId/interface/CSCTriggerNumbering.h"
00023
00024
00025 MuonScenarioBuilder::MuonScenarioBuilder( Alignable* alignable )
00026 {
00027
00028 theAlignableMuon = dynamic_cast<AlignableMuon*>( alignable );
00029
00030 if ( !theAlignableMuon )
00031 throw cms::Exception("TypeMismatch") << "Argument is not an AlignableMuon";
00032
00033 }
00034
00035
00036
00037 void MuonScenarioBuilder::applyScenario( const edm::ParameterSet& scenario )
00038 {
00039
00040
00041 theScenario = scenario;
00042 theModifierCounter = 0;
00043
00044
00045 if ( this->hasParameter_( "seed", theScenario ) )
00046 theModifier.setSeed( static_cast<long>(theScenario.getParameter<int>("seed")) );
00047 else
00048 throw cms::Exception("BadConfig") << "No generator seed defined!";
00049
00050
00051
00052
00053 std::vector<Alignable*> dtBarrel = theAlignableMuon->DTBarrel();
00054 this->decodeMovements_( theScenario, dtBarrel, "DTBarrel" );
00055
00056 std::vector<Alignable*> cscEndcaps = theAlignableMuon->CSCEndcaps();
00057 this->decodeMovements_( theScenario, cscEndcaps, "CSCEndcap" );
00058
00059 this->moveDTSectors(theScenario);
00060 this->moveCSCSectors(theScenario);
00061 this->moveMuon(theScenario);
00062
00063 edm::LogInfo("TrackerScenarioBuilder")
00064 << "Applied modifications to " << theModifierCounter << " alignables";
00065
00066 }
00067
00068
00069
00070 std::vector<float> MuonScenarioBuilder::extractParameters(const edm::ParameterSet& pSet, const char *blockId) {
00071
00072 double scale_ = 0, scaleError_ = 0, phiX_ = 0, phiY_ = 0, phiZ_ = 0;
00073 double dX_ = 0, dY_ = 0, dZ_ = 0;
00074 std::string distribution_;
00075 std::ostringstream error;
00076 edm::ParameterSet Parameters = this->getParameterSet_((std::string)blockId, pSet);
00077 std::vector<std::string> parameterNames = Parameters.getParameterNames();
00078 for ( std::vector<std::string>::iterator iParam = parameterNames.begin(); iParam != parameterNames.end(); iParam++ ) {
00079 if ( (*iParam) == "scale" ) scale_ = Parameters.getParameter<double>( *iParam );
00080 else if ( (*iParam) == "distribution" ) distribution_ = Parameters.getParameter<std::string>( *iParam );
00081 else if ( (*iParam) == "scaleError" ) scaleError_ = Parameters.getParameter<double>( *iParam );
00082 else if ( (*iParam) == "phiX" ) phiX_ = Parameters.getParameter<double>( *iParam );
00083 else if ( (*iParam) == "phiY" ) phiY_ = Parameters.getParameter<double>( *iParam );
00084 else if ( (*iParam) == "phiZ" ) phiZ_ = Parameters.getParameter<double>( *iParam );
00085 else if ( (*iParam) == "dX" ) dX_ = Parameters.getParameter<double>( *iParam );
00086 else if ( (*iParam) == "dY" ) dY_ = Parameters.getParameter<double>( *iParam );
00087 else if ( (*iParam) == "dZ" ) dZ_ = Parameters.getParameter<double>( *iParam );
00088 else if ( Parameters.retrieve( *iParam ).typeCode() != 'P' )
00089 {
00090 if ( !error.str().length() ) error << "Unknown parameter name(s): ";
00091 error << " " << *iParam;
00092 }
00093 }
00094 std::vector<float> param;
00095 param.push_back(scale_); param.push_back(scaleError_);
00096 param.push_back(phiX_); param.push_back(phiY_);
00097 param.push_back(phiZ_); param.push_back(dX_);
00098 param.push_back(dY_); param.push_back(dZ_);
00099 if( distribution_ == "gaussian" )
00100 param.push_back(0);
00101 else if ( distribution_ == "flat" )
00102 param.push_back(1);
00103 else if ( distribution_ == "fix" )
00104 param.push_back(2);
00105
00106 return param;
00107
00108 }
00109
00110
00111 void MuonScenarioBuilder::moveDTSectors(const edm::ParameterSet& pSet) {
00112
00113 std::vector<Alignable *> DTchambers = theAlignableMuon->DTChambers();
00114
00115 std::vector<float> param = this->extractParameters(pSet, "DTSectors");
00116 float scale_ = param[0]; float scaleError_ = param[1];
00117 float phiX_ = param[2]; float phiY_ = param[3]; float phiZ_ = param[4];
00118 float dX_ = param[5]; float dY_ = param[6]; float dZ_ = param[7];
00119 float dist_ = param[8];
00120
00121 float dx = scale_*dX_; float dy = scale_*dY_; float dz = scale_*dZ_;
00122 float phix = scale_*phiX_; float phiy = scale_*phiY_; float phiz = scale_*phiZ_;
00123 float errorx = scaleError_*dX_; float errory = scaleError_*dY_; float errorz = scaleError_*dZ_;
00124 float errorphix = scaleError_*phiX_; float errorphiy = scaleError_*phiY_; float errorphiz = scaleError_*phiZ_;
00125 std::vector<float> errorDisp;
00126 errorDisp.push_back(errorx); errorDisp.push_back(errory); errorDisp.push_back(errorz);
00127 std::vector<float> errorRotation;
00128 errorRotation.push_back(errorphix); errorRotation.push_back(errorphiy); errorRotation.push_back(errorphiz);
00129
00130 int index[5][4][14];
00131 int counter = 0;
00132
00133 for(std::vector<Alignable *>::iterator iter = DTchambers.begin(); iter != DTchambers.end(); ++iter) {
00134 DTChamberId myId((*iter)->geomDetId().rawId());
00135 index[myId.wheel()+2][myId.station()-1][myId.sector()-1] = counter;
00136 counter++;
00137 }
00138 for(int wheel = 0; wheel < 5; wheel++) {
00139 for(int sector = 0; sector < 12; sector++) {
00140 std::vector<float> disp;
00141 std::vector<float> rotation;
00142 if( dist_ == 0 ) {
00143 const std::vector<float> disp_ = theMuonModifier.gaussianRandomVector(dx, dy, dz);
00144 const std::vector<float> rotation_ = theMuonModifier.gaussianRandomVector(phix, phiy, phiz);
00145 disp.push_back(disp_[0]); disp.push_back(disp_[1]); disp.push_back(disp_[2]);
00146 rotation.push_back(rotation_[0]); rotation.push_back(rotation_[1]); rotation.push_back(rotation_[2]);
00147 } else if (dist_ == 1) {
00148 const std::vector<float> disp_ = theMuonModifier.flatRandomVector(dx, dy, dz);
00149 const std::vector<float> rotation_ = theMuonModifier.flatRandomVector(phix, phiy, phiz);
00150 disp.push_back(disp_[0]); disp.push_back(disp_[1]); disp.push_back(disp_[2]);
00151 rotation.push_back(rotation_[0]); rotation.push_back(rotation_[1]); rotation.push_back(rotation_[2]);
00152 } else {
00153 disp.push_back(dx); disp.push_back(dy); disp.push_back(dz);
00154 rotation.push_back(phix); rotation.push_back(phiy); rotation.push_back(phiz);
00155 }
00156 for(int station = 0; station < 4; station++) {
00157 Alignable *myAlign = DTchambers.at(index[wheel][station][sector]);
00158 this->moveChamberInSector(myAlign, disp, rotation, errorDisp, errorRotation);
00159 if(sector == 3 && station == 3) {
00160 Alignable *myAlignD = DTchambers.at(index[wheel][station][12]);
00161 this->moveChamberInSector(myAlignD, disp, rotation, errorDisp, errorRotation);
00162 } else if(sector == 9 && station == 3) {
00163 Alignable *myAlignD = DTchambers.at(index[wheel][station][13]);
00164 this->moveChamberInSector(myAlignD, disp, rotation, errorDisp, errorRotation);
00165 }
00166 }
00167 }
00168 }
00169 }
00170
00171
00172
00173
00174 void MuonScenarioBuilder::moveCSCSectors(const edm::ParameterSet& pSet) {
00175
00176 std::vector<Alignable *> CSCchambers = theAlignableMuon->CSCChambers();
00177
00178 std::vector<float> param = this->extractParameters(pSet, "CSCSectors");
00179 float scale_ = param[0]; float scaleError_ = param[1];
00180 float phiX_ = param[2]; float phiY_ = param[3]; float phiZ_ = param[4];
00181 float dX_ = param[5]; float dY_ = param[6]; float dZ_ = param[7];
00182 float dist_ = param[8];
00183
00184 float dx = scale_*dX_; float dy = scale_*dY_; float dz = scale_*dZ_;
00185 float phix = scale_*phiX_; float phiy = scale_*phiY_; float phiz = scale_*phiZ_;
00186 float errorx = scaleError_*dX_; float errory = scaleError_*dY_; float errorz = scaleError_*dZ_;
00187 float errorphix = scaleError_*phiX_; float errorphiy = scaleError_*phiY_; float errorphiz = scaleError_*phiZ_;
00188 std::vector<float> errorDisp;
00189 errorDisp.push_back(errorx); errorDisp.push_back(errory); errorDisp.push_back(errorz);
00190 std::vector<float> errorRotation;
00191 errorRotation.push_back(errorphix); errorRotation.push_back(errorphiy); errorRotation.push_back(errorphiz);
00192
00193 int index[2][4][4][36];
00194 int sector_index[2][4][4][36];
00195 int counter = 0;
00196
00197 for(std::vector<Alignable *>::iterator iter = CSCchambers.begin(); iter != CSCchambers.end(); ++iter) {
00198 CSCDetId myId((*iter)->geomDetId().rawId());
00199 index[myId.endcap()-1][myId.station()-1][myId.ring()-1][myId.chamber()-1] = counter;
00200 sector_index[myId.endcap()-1][myId.station()-1][myId.ring()-1][myId.chamber()-1] = CSCTriggerNumbering::sectorFromTriggerLabels(CSCTriggerNumbering::triggerSectorFromLabels(myId),CSCTriggerNumbering::triggerSubSectorFromLabels(myId) , myId.station());
00201 counter++;
00202 }
00203 for(int endcap = 0; endcap < 2; endcap++) {
00204 for(int ring = 0; ring < 2; ring++) {
00205 for(int sector = 1; sector < 7; sector++) {
00206 std::vector<float> disp;
00207 std::vector<float> rotation;
00208 if( dist_ == 0 ) {
00209 const std::vector<float> disp_ = theMuonModifier.gaussianRandomVector(dx, dy, dz);
00210 const std::vector<float> rotation_ = theMuonModifier.gaussianRandomVector(phix, phiy, phiz);
00211 disp.push_back(disp_[0]); disp.push_back(disp_[1]); disp.push_back(disp_[2]);
00212 rotation.push_back(rotation_[0]); rotation.push_back(rotation_[1]); rotation.push_back(rotation_[2]);
00213 } else if (dist_ == 1) {
00214 const std::vector<float> disp_ = theMuonModifier.flatRandomVector(dx, dy, dz);
00215 const std::vector<float> rotation_ = theMuonModifier.flatRandomVector(phix, phiy, phiz);
00216 disp.push_back(disp_[0]); disp.push_back(disp_[1]); disp.push_back(disp_[2]);
00217 rotation.push_back(rotation_[0]); rotation.push_back(rotation_[1]); rotation.push_back(rotation_[2]);
00218 } else {
00219 disp.push_back(dx); disp.push_back(dy); disp.push_back(dz);
00220 rotation.push_back(phix); rotation.push_back(phiy); rotation.push_back(phiz);
00221 }
00222
00223 for(int station = 0; station < 4; station++) {
00224 if(station == 0) {
00225 int r_ring[2];
00226 if(ring == 0) {
00227 r_ring[0] = 0; r_ring[1] = 3;
00228 } else {
00229 r_ring[0] = 1; r_ring[1] = 2;
00230 }
00231 for(int r_counter = 0; r_counter < 2; r_counter++) {
00232 for(int chamber = 0; chamber < 36; chamber++) {
00233 if(sector == (sector_index[endcap][station][r_ring[r_counter]][chamber]+1)/2) {
00234 Alignable *myAlign = CSCchambers.at(index[endcap][station][r_ring[r_counter]][chamber]);
00235 this->moveChamberInSector(myAlign, disp, rotation, errorDisp, errorRotation);
00236 }
00237 }
00238 }
00239 } else if(station == 3 && ring == 1) {
00240 continue;
00241 } else {
00242 for(int chamber = 0; chamber < 36; chamber++) {
00243 if(ring == 0 && chamber > 17) continue;
00244 if(sector == sector_index[endcap][station][ring][chamber]) {
00245 Alignable *myAlign = CSCchambers.at(index[endcap][station][ring][chamber]);
00246 this->moveChamberInSector(myAlign, disp, rotation, errorDisp, errorRotation);
00247 }
00248 }
00249 }
00250 }
00251 }
00252 }
00253 }
00254 }
00255
00256
00257
00258 void MuonScenarioBuilder::moveMuon(const edm::ParameterSet& pSet) {
00259
00260 std::vector<Alignable *> DTbarrel = theAlignableMuon->DTBarrel();
00261 std::vector<Alignable *> CSCendcaps = theAlignableMuon->CSCEndcaps();
00262
00263 std::vector<float> param = this->extractParameters(pSet, "Muon");
00264 float scale_ = param[0]; float scaleError_ = param[1];
00265 float phiX_ = param[2]; float phiY_ = param[3]; float phiZ_ = param[4];
00266 float dX_ = param[5]; float dY_ = param[6]; float dZ_ = param[7];
00267 float dist_ = param[8];
00268 float dx = scale_*dX_; float dy = scale_*dY_; float dz = scale_*dZ_;
00269 float phix = scale_*phiX_; float phiy = scale_*phiY_; float phiz = scale_*phiZ_;
00270 float errorx = scaleError_*dX_; float errory = scaleError_*dY_; float errorz = scaleError_*dZ_;
00271 float errorphix = scaleError_*phiX_; float errorphiy = scaleError_*phiY_; float errorphiz = scaleError_*phiZ_;
00272
00273 std::vector<float> disp;
00274 std::vector<float> rotation;
00275 if( dist_ == 0 ) {
00276 const std::vector<float> disp_ = theMuonModifier.gaussianRandomVector(dx, dy, dz);
00277 const std::vector<float> rotation_ = theMuonModifier.gaussianRandomVector(phix, phiy, phiz);
00278 disp.push_back(disp_[0]); disp.push_back(disp_[1]); disp.push_back(disp_[2]);
00279 rotation.push_back(rotation_[0]); rotation.push_back(rotation_[1]); rotation.push_back(rotation_[2]);
00280 } else if (dist_ == 1) {
00281 const std::vector<float> disp_ = theMuonModifier.flatRandomVector(dx, dy, dz);
00282 const std::vector<float> rotation_ = theMuonModifier.flatRandomVector(phix, phiy, phiz);
00283 disp.push_back(disp_[0]); disp.push_back(disp_[1]); disp.push_back(disp_[2]);
00284 rotation.push_back(rotation_[0]); rotation.push_back(rotation_[1]); rotation.push_back(rotation_[2]);
00285 } else {
00286 disp.push_back(dx); disp.push_back(dy); disp.push_back(dz);
00287 rotation.push_back(phix); rotation.push_back(phiy); rotation.push_back(phiz);
00288 }
00289 for(std::vector<Alignable *>::iterator iter = DTbarrel.begin(); iter != DTbarrel.end(); ++iter) {
00290 theMuonModifier.moveAlignable( *iter, false, true, disp[0], disp[1], disp[2] );
00291 theMuonModifier.rotateAlignable( *iter, false, true, rotation[0], rotation[1], rotation[2] );
00292 theMuonModifier.addAlignmentPositionError( *iter, errorx, errory, errorz );
00293 theMuonModifier.addAlignmentPositionErrorFromRotation( *iter, errorphix, errorphiy, errorphiz );
00294 }
00295 for(std::vector<Alignable *>::iterator iter = CSCendcaps.begin(); iter != CSCendcaps.end(); ++iter) {
00296 theMuonModifier.moveAlignable( *iter, false, true, disp[0], disp[1], disp[2] );
00297 theMuonModifier.rotateAlignable( *iter, false, true, rotation[0], rotation[1], rotation[2] );
00298 theMuonModifier.addAlignmentPositionError( *iter, errorx, errory, errorz );
00299 theMuonModifier.addAlignmentPositionErrorFromRotation( *iter, errorphix, errorphiy, errorphiz );
00300 }
00301
00302 }
00303
00304
00305
00306 void MuonScenarioBuilder::moveChamberInSector(Alignable *chamber, std::vector<float> disp, std::vector<float>rotation, std::vector<float> dispError, std::vector<float> rotationError) {
00307
00308 align::RotationType rotx( Basic3DVector<float>(1.0, 0.0, 0.0), rotation[0] );
00309 align::RotationType roty( Basic3DVector<float>(0.0, 1.0, 0.0), rotation[1] );
00310 align::RotationType rotz( Basic3DVector<float>(0.0, 0.0, 1.0), rotation[2] );
00311 align::RotationType rot = rotz * roty * rotx;
00312 GlobalPoint pos = chamber->globalPosition();
00313 GlobalPoint dispRot(pos.basicVector()-rot*pos.basicVector());
00314 disp[0] += dispRot.x(); disp[1] += dispRot.y(); disp[2] += dispRot.z();
00315 theMuonModifier.moveAlignable( chamber, false, true, disp[0], disp[1], disp[2] );
00316 theMuonModifier.rotateAlignable( chamber, false, true, rotation[0], rotation[1], rotation[2] );
00317 theMuonModifier.addAlignmentPositionError( chamber, dispError[0], dispError[1], dispError[2] );
00318 theMuonModifier.addAlignmentPositionErrorFromRotation( chamber, rotationError[0], rotationError[1], rotationError[2] );
00319
00320 }