Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 /** \file
0002  *
0003  *  $Date: 2011/06/07 19:38:24 $
0004  *  $Revision: 1.9 $
0005  *  \author Andre Sznajder - UERJ(Brazil)
0006  */
0007 
0008 #include <string>
0009 #include <iostream>
0010 #include <sstream>
0011 #include <algorithm>
0012 
0013 // Framework
0014 #include "FWCore/Utilities/interface/Exception.h"
0015 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0016 
0017 // Alignment
0018 
0019 #include "Alignment/MuonAlignment/interface/MuonScenarioBuilder.h"
0020 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0021 #include "Alignment/CommonAlignment/interface/Alignable.h"
0022 #include "DataFormats/MuonDetId/interface/CSCTriggerNumbering.h"
0023 
0024 #include "DataFormats/MuonDetId/interface/GEMDetId.h"
0025 
0026 //__________________________________________________________________________________________________
0027 MuonScenarioBuilder::MuonScenarioBuilder(Alignable* alignable)
0028     :  // muon alignable IDs are (currently) independent of the geometry
0029       MisalignmentScenarioBuilder(AlignableObjectId::Geometry::PhaseI) {
0030   theAlignableMuon = dynamic_cast<AlignableMuon*>(alignable);
0031 
0032   if (!theAlignableMuon)
0033     throw cms::Exception("TypeMismatch") << "Argument is not an AlignableMuon";
0034 }
0035 
0036 //__________________________________________________________________________________________________
0037 void MuonScenarioBuilder::applyScenario(const edm::ParameterSet& scenario) {
0038   // Apply the scenario to all main components of Muon.
0039   theScenario = scenario;
0040   theModifierCounter = 0;
0041 
0042   // Seed is set at top-level, and is mandatory
0043   if (this->hasParameter_("seed", theScenario))
0044     theModifier.setSeed(static_cast<long>(theScenario.getParameter<int>("seed")));
0045   else
0046     throw cms::Exception("BadConfig") << "No generator seed defined!";
0047 
0048   // DT Barrel
0049   const auto& dtBarrel = theAlignableMuon->DTBarrel();
0050   this->decodeMovements_(theScenario, dtBarrel, "DTBarrel");
0051   // Endcap
0052   const auto& cscEndcaps = theAlignableMuon->CSCEndcaps();
0053   this->decodeMovements_(theScenario, cscEndcaps, "CSCEndcap");
0054   const auto& gemEndcaps = theAlignableMuon->GEMEndcaps();
0055   this->decodeMovements_(theScenario, gemEndcaps, "GEMEndcap");
0056 
0057   this->moveDTSectors(theScenario);
0058   this->moveCSCSectors(theScenario);
0059   this->moveGEMSectors(theScenario);
0060   this->moveMuon(theScenario);
0061 
0062   edm::LogInfo("TrackerScenarioBuilder") << "Applied modifications to " << theModifierCounter << " alignables";
0063 }
0064 
0065 align::Scalars MuonScenarioBuilder::extractParameters(const edm::ParameterSet& pSet, const char* blockId) {
0066   double scale_ = 0, scaleError_ = 0, phiX_ = 0, phiY_ = 0, phiZ_ = 0;
0067   double dX_ = 0, dY_ = 0, dZ_ = 0;
0068   std::string distribution_;
0069   std::ostringstream error;
0070   edm::ParameterSet Parameters = this->getParameterSet_((std::string)blockId, pSet);
0071   std::vector<std::string> parameterNames = Parameters.getParameterNames();
0072   for (std::vector<std::string>::iterator iParam = parameterNames.begin(); iParam != parameterNames.end(); iParam++) {
0073     if ((*iParam) == "scale")
0074       scale_ = Parameters.getParameter<double>(*iParam);
0075     else if ((*iParam) == "distribution")
0076       distribution_ = Parameters.getParameter<std::string>(*iParam);
0077     else if ((*iParam) == "scaleError")
0078       scaleError_ = Parameters.getParameter<double>(*iParam);
0079     else if ((*iParam) == "phiX")
0080       phiX_ = Parameters.getParameter<double>(*iParam);
0081     else if ((*iParam) == "phiY")
0082       phiY_ = Parameters.getParameter<double>(*iParam);
0083     else if ((*iParam) == "phiZ")
0084       phiZ_ = Parameters.getParameter<double>(*iParam);
0085     else if ((*iParam) == "dX")
0086       dX_ = Parameters.getParameter<double>(*iParam);
0087     else if ((*iParam) == "dY")
0088       dY_ = Parameters.getParameter<double>(*iParam);
0089     else if ((*iParam) == "dZ")
0090       dZ_ = Parameters.getParameter<double>(*iParam);
0091     else if (Parameters.retrieve(*iParam).typeCode() != 'P') {  // Add unknown parameter to list
0092       if (!error.str().length())
0093         error << "Unknown parameter name(s): ";
0094       error << " " << *iParam;
0095     }
0096   }
0097   align::Scalars param;
0098   param.push_back(scale_);
0099   param.push_back(scaleError_);
0100   param.push_back(phiX_);
0101   param.push_back(phiY_);
0102   param.push_back(phiZ_);
0103   param.push_back(dX_);
0104   param.push_back(dY_);
0105   param.push_back(dZ_);
0106   if (distribution_ == "gaussian")
0107     param.push_back(0);
0108   else if (distribution_ == "flat")
0109     param.push_back(1);
0110   else if (distribution_ == "fix")
0111     param.push_back(2);
0112 
0113   return param;
0114 }
0115 
0116 //_____________________________________________________________________________________________________
0117 void MuonScenarioBuilder::moveDTSectors(const edm::ParameterSet& pSet) {
0118   const auto& DTchambers = theAlignableMuon->DTChambers();
0119   //Take parameters
0120   align::Scalars param = this->extractParameters(pSet, "DTSectors");
0121   double scale_ = param[0];
0122   double scaleError_ = param[1];
0123   double phiX_ = param[2];
0124   double phiY_ = param[3];
0125   double phiZ_ = param[4];
0126   double dX_ = param[5];
0127   double dY_ = param[6];
0128   double dZ_ = param[7];
0129   double dist_ = param[8];
0130 
0131   double dx = scale_ * dX_;
0132   double dy = scale_ * dY_;
0133   double dz = scale_ * dZ_;
0134   double phix = scale_ * phiX_;
0135   double phiy = scale_ * phiY_;
0136   double phiz = scale_ * phiZ_;
0137   double errorx = scaleError_ * dX_;
0138   double errory = scaleError_ * dY_;
0139   double errorz = scaleError_ * dZ_;
0140   double errorphix = scaleError_ * phiX_;
0141   double errorphiy = scaleError_ * phiY_;
0142   double errorphiz = scaleError_ * phiZ_;
0143   align::Scalars errorDisp;
0144   errorDisp.push_back(errorx);
0145   errorDisp.push_back(errory);
0146   errorDisp.push_back(errorz);
0147   align::Scalars errorRotation;
0148   errorRotation.push_back(errorphix);
0149   errorRotation.push_back(errorphiy);
0150   errorRotation.push_back(errorphiz);
0151 
0152   int index[5][4][14];
0153   std::fill_n(index[0][0], 5 * 4 * 14, -1);  // initialize to -1
0154   int counter = 0;
0155   //Create and index for the chambers in the Alignable vector
0156   for (const auto& iter : DTchambers) {
0157     DTChamberId myId(iter->geomDetId().rawId());
0158     index[myId.wheel() + 2][myId.station() - 1][myId.sector() - 1] = counter;
0159     counter++;
0160   }
0161   for (int wheel = 0; wheel < 5; wheel++) {
0162     for (int sector = 0; sector < 12; sector++) {
0163       align::Scalars disp;
0164       align::Scalars rotation;
0165       if (dist_ == 0) {
0166         const std::vector<float> disp_ = theMuonModifier.gaussianRandomVector(dx, dy, dz);
0167         const std::vector<float> rotation_ = theMuonModifier.gaussianRandomVector(phix, phiy, phiz);
0168         disp.push_back(disp_[0]);
0169         disp.push_back(disp_[1]);
0170         disp.push_back(disp_[2]);
0171         rotation.push_back(rotation_[0]);
0172         rotation.push_back(rotation_[1]);
0173         rotation.push_back(rotation_[2]);
0174       } else if (dist_ == 1) {
0175         const std::vector<float> disp_ = theMuonModifier.flatRandomVector(dx, dy, dz);
0176         const std::vector<float> rotation_ = theMuonModifier.flatRandomVector(phix, phiy, phiz);
0177         disp.push_back(disp_[0]);
0178         disp.push_back(disp_[1]);
0179         disp.push_back(disp_[2]);
0180         rotation.push_back(rotation_[0]);
0181         rotation.push_back(rotation_[1]);
0182         rotation.push_back(rotation_[2]);
0183       } else {
0184         disp.push_back(dx);
0185         disp.push_back(dy);
0186         disp.push_back(dz);
0187         rotation.push_back(phix);
0188         rotation.push_back(phiy);
0189         rotation.push_back(phiz);
0190       }
0191       for (int station = 0; station < 4; station++) {
0192         Alignable* myAlign = DTchambers.at(index[wheel][station][sector]);
0193         this->moveChamberInSector(myAlign, disp, rotation, errorDisp, errorRotation);
0194         if (sector == 3 && station == 3) {
0195           Alignable* myAlignD = DTchambers.at(index[wheel][station][12]);
0196           this->moveChamberInSector(myAlignD, disp, rotation, errorDisp, errorRotation);
0197         } else if (sector == 9 && station == 3) {
0198           Alignable* myAlignD = DTchambers.at(index[wheel][station][13]);
0199           this->moveChamberInSector(myAlignD, disp, rotation, errorDisp, errorRotation);
0200         }
0201       }
0202     }
0203   }
0204 }
0205 
0206 //______________________________________________________________________________________________________
0207 void MuonScenarioBuilder::moveCSCSectors(const edm::ParameterSet& pSet) {
0208   const auto& CSCchambers = theAlignableMuon->CSCChambers();
0209   //Take Parameters
0210   align::Scalars param = this->extractParameters(pSet, "CSCSectors");
0211   double scale_ = param[0];
0212   double scaleError_ = param[1];
0213   double phiX_ = param[2];
0214   double phiY_ = param[3];
0215   double phiZ_ = param[4];
0216   double dX_ = param[5];
0217   double dY_ = param[6];
0218   double dZ_ = param[7];
0219   double dist_ = param[8];
0220 
0221   double dx = scale_ * dX_;
0222   double dy = scale_ * dY_;
0223   double dz = scale_ * dZ_;
0224   double phix = scale_ * phiX_;
0225   double phiy = scale_ * phiY_;
0226   double phiz = scale_ * phiZ_;
0227   double errorx = scaleError_ * dX_;
0228   double errory = scaleError_ * dY_;
0229   double errorz = scaleError_ * dZ_;
0230   double errorphix = scaleError_ * phiX_;
0231   double errorphiy = scaleError_ * phiY_;
0232   double errorphiz = scaleError_ * phiZ_;
0233   align::Scalars errorDisp;
0234   errorDisp.push_back(errorx);
0235   errorDisp.push_back(errory);
0236   errorDisp.push_back(errorz);
0237   align::Scalars errorRotation;
0238   errorRotation.push_back(errorphix);
0239   errorRotation.push_back(errorphiy);
0240   errorRotation.push_back(errorphiz);
0241 
0242   int index[2][4][4][36];
0243   int sector_index[2][4][4][36];
0244   std::fill_n(index[0][0][0], 2 * 4 * 4 * 36, -1);         // initialize to -1
0245   std::fill_n(sector_index[0][0][0], 2 * 4 * 4 * 36, -1);  // initialize to -1
0246   int counter = 0;
0247   //Create an index for the chambers in the alignable vector
0248   for (const auto& iter : CSCchambers) {
0249     CSCDetId myId(iter->geomDetId().rawId());
0250     index[myId.endcap() - 1][myId.station() - 1][myId.ring() - 1][myId.chamber() - 1] = counter;
0251     sector_index[myId.endcap() - 1][myId.station() - 1][myId.ring() - 1][myId.chamber() - 1] =
0252         CSCTriggerNumbering::sectorFromTriggerLabels(CSCTriggerNumbering::triggerSectorFromLabels(myId),
0253                                                      CSCTriggerNumbering::triggerSubSectorFromLabels(myId),
0254                                                      myId.station());
0255     counter++;
0256   }
0257   for (int endcap = 0; endcap < 2; endcap++) {
0258     for (int ring = 0; ring < 2; ring++) {
0259       for (int sector = 1; sector < 7; sector++) {
0260         align::Scalars disp;
0261         align::Scalars rotation;
0262         if (dist_ == 0) {
0263           const std::vector<float> disp_ = theMuonModifier.gaussianRandomVector(dx, dy, dz);
0264           const std::vector<float> rotation_ = theMuonModifier.gaussianRandomVector(phix, phiy, phiz);
0265           disp.push_back(disp_[0]);
0266           disp.push_back(disp_[1]);
0267           disp.push_back(disp_[2]);
0268           rotation.push_back(rotation_[0]);
0269           rotation.push_back(rotation_[1]);
0270           rotation.push_back(rotation_[2]);
0271         } else if (dist_ == 1) {
0272           const std::vector<float> disp_ = theMuonModifier.flatRandomVector(dx, dy, dz);
0273           const std::vector<float> rotation_ = theMuonModifier.flatRandomVector(phix, phiy, phiz);
0274           disp.push_back(disp_[0]);
0275           disp.push_back(disp_[1]);
0276           disp.push_back(disp_[2]);
0277           rotation.push_back(rotation_[0]);
0278           rotation.push_back(rotation_[1]);
0279           rotation.push_back(rotation_[2]);
0280         } else {
0281           disp.push_back(dx);
0282           disp.push_back(dy);
0283           disp.push_back(dz);
0284           rotation.push_back(phix);
0285           rotation.push_back(phiy);
0286           rotation.push_back(phiz);
0287         }
0288         //Different cases are considered in order to fit endcap geometry
0289         for (int station = 0; station < 4; station++) {
0290           if (station == 0) {
0291             int r_ring[2];
0292             if (ring == 0) {
0293               r_ring[0] = 0;
0294               r_ring[1] = 3;
0295             } else {
0296               r_ring[0] = 1;
0297               r_ring[1] = 2;
0298             }
0299             for (int r_counter = 0; r_counter < 2; r_counter++) {
0300               for (int chamber = 0; chamber < 36; chamber++) {
0301                 if (sector == (sector_index[endcap][station][r_ring[r_counter]][chamber] + 1) / 2) {
0302                   Alignable* myAlign = CSCchambers.at(index[endcap][station][r_ring[r_counter]][chamber]);
0303                   this->moveChamberInSector(myAlign, disp, rotation, errorDisp, errorRotation);
0304                 }
0305               }
0306             }
0307           } else if (station == 3 && ring == 1) {
0308             continue;
0309           } else {
0310             for (int chamber = 0; chamber < 36; chamber++) {
0311               if (ring == 0 && chamber > 17)
0312                 continue;
0313               if (sector == sector_index[endcap][station][ring][chamber]) {
0314                 Alignable* myAlign = CSCchambers.at(index[endcap][station][ring][chamber]);
0315                 this->moveChamberInSector(myAlign, disp, rotation, errorDisp, errorRotation);
0316               }
0317             }
0318           }
0319         }
0320       }
0321     }
0322   }
0323 }
0324 
0325 //______________________________________________________________________________________________________
0326 void MuonScenarioBuilder::moveGEMSectors(const edm::ParameterSet& pSet) {
0327   const auto& GEMSuperChambers = theAlignableMuon->GEMSuperChambers();
0328   //Take Parameters
0329   align::Scalars param = this->extractParameters(pSet, "GEMSectors");
0330   double scale_ = param[0];
0331   double scaleError_ = param[1];
0332   double phiX_ = param[2];
0333   double phiY_ = param[3];
0334   double phiZ_ = param[4];
0335   double dX_ = param[5];
0336   double dY_ = param[6];
0337   double dZ_ = param[7];
0338 
0339   double dx = scale_ * dX_;
0340   double dy = scale_ * dY_;
0341   double dz = scale_ * dZ_;
0342   double phix = scale_ * phiX_;
0343   double phiy = scale_ * phiY_;
0344   double phiz = scale_ * phiZ_;
0345   double errorx = scaleError_ * dX_;
0346   double errory = scaleError_ * dY_;
0347   double errorz = scaleError_ * dZ_;
0348   double errorphix = scaleError_ * phiX_;
0349   double errorphiy = scaleError_ * phiY_;
0350   double errorphiz = scaleError_ * phiZ_;
0351   align::Scalars errorDisp;
0352   errorDisp.push_back(errorx);
0353   errorDisp.push_back(errory);
0354   errorDisp.push_back(errorz);
0355   align::Scalars errorRotation;
0356   errorRotation.push_back(errorphix);
0357   errorRotation.push_back(errorphiy);
0358   errorRotation.push_back(errorphiz);
0359 
0360   //Create an index for the chambers in the alignable vector
0361   for (const auto& iter : GEMSuperChambers) {
0362     align::Scalars disp;
0363     align::Scalars rotation;
0364     const std::vector<float> disp_ = theMuonModifier.gaussianRandomVector(dx, dy, dz);
0365     disp.push_back(disp_[0]);
0366     disp.push_back(disp_[1]);
0367     disp.push_back(disp_[2]);
0368     const std::vector<float> rotation_ = theMuonModifier.flatRandomVector(phix, phiy, phiz);
0369     rotation.push_back(rotation_[0]);
0370     rotation.push_back(rotation_[1]);
0371     rotation.push_back(rotation_[2]);
0372     this->moveChamberInSector(iter, disp, rotation, errorDisp, errorRotation);
0373   }
0374 }
0375 
0376 void MuonScenarioBuilder::moveMuon(const edm::ParameterSet& pSet) {
0377   const auto& DTbarrel = theAlignableMuon->DTBarrel();
0378   const auto& CSCendcaps = theAlignableMuon->CSCEndcaps();
0379   const auto& GEMendcaps = theAlignableMuon->GEMEndcaps();
0380   //Take Parameters
0381   align::Scalars param = this->extractParameters(pSet, "Muon");
0382   double scale_ = param[0];
0383   double scaleError_ = param[1];
0384   double phiX_ = param[2];
0385   double phiY_ = param[3];
0386   double phiZ_ = param[4];
0387   double dX_ = param[5];
0388   double dY_ = param[6];
0389   double dZ_ = param[7];
0390   double dist_ = param[8];
0391   double dx = scale_ * dX_;
0392   double dy = scale_ * dY_;
0393   double dz = scale_ * dZ_;
0394   double phix = scale_ * phiX_;
0395   double phiy = scale_ * phiY_;
0396   double phiz = scale_ * phiZ_;
0397   double errorx = scaleError_ * dX_;
0398   double errory = scaleError_ * dY_;
0399   double errorz = scaleError_ * dZ_;
0400   double errorphix = scaleError_ * phiX_;
0401   double errorphiy = scaleError_ * phiY_;
0402   double errorphiz = scaleError_ * phiZ_;
0403   //Create an index for the chambers in the alignable vector
0404   align::Scalars disp;
0405   align::Scalars rotation;
0406   if (dist_ == 0) {
0407     const std::vector<float> disp_ = theMuonModifier.gaussianRandomVector(dx, dy, dz);
0408     const std::vector<float> rotation_ = theMuonModifier.gaussianRandomVector(phix, phiy, phiz);
0409     disp.push_back(disp_[0]);
0410     disp.push_back(disp_[1]);
0411     disp.push_back(disp_[2]);
0412     rotation.push_back(rotation_[0]);
0413     rotation.push_back(rotation_[1]);
0414     rotation.push_back(rotation_[2]);
0415   } else if (dist_ == 1) {
0416     const std::vector<float> disp_ = theMuonModifier.flatRandomVector(dx, dy, dz);
0417     const std::vector<float> rotation_ = theMuonModifier.flatRandomVector(phix, phiy, phiz);
0418     disp.push_back(disp_[0]);
0419     disp.push_back(disp_[1]);
0420     disp.push_back(disp_[2]);
0421     rotation.push_back(rotation_[0]);
0422     rotation.push_back(rotation_[1]);
0423     rotation.push_back(rotation_[2]);
0424   } else {
0425     disp.push_back(dx);
0426     disp.push_back(dy);
0427     disp.push_back(dz);
0428     rotation.push_back(phix);
0429     rotation.push_back(phiy);
0430     rotation.push_back(phiz);
0431   }
0432   for (const auto& iter : DTbarrel) {
0433     theMuonModifier.moveAlignable(iter, false, true, disp[0], disp[1], disp[2]);
0434     theMuonModifier.rotateAlignable(iter, false, true, rotation[0], rotation[1], rotation[2]);
0435     theMuonModifier.addAlignmentPositionError(iter, errorx, errory, errorz);
0436     theMuonModifier.addAlignmentPositionErrorFromRotation(iter, errorphix, errorphiy, errorphiz);
0437   }
0438   for (const auto& iter : CSCendcaps) {
0439     theMuonModifier.moveAlignable(iter, false, true, disp[0], disp[1], disp[2]);
0440     theMuonModifier.rotateAlignable(iter, false, true, rotation[0], rotation[1], rotation[2]);
0441     theMuonModifier.addAlignmentPositionError(iter, errorx, errory, errorz);
0442     theMuonModifier.addAlignmentPositionErrorFromRotation(iter, errorphix, errorphiy, errorphiz);
0443   }
0444   for (const auto& iter : GEMendcaps) {
0445     theMuonModifier.moveAlignable(iter, false, true, disp[0], disp[1], disp[2]);
0446     theMuonModifier.rotateAlignable(iter, false, true, rotation[0], rotation[1], rotation[2]);
0447     theMuonModifier.addAlignmentPositionError(iter, errorx, errory, errorz);
0448     theMuonModifier.addAlignmentPositionErrorFromRotation(iter, errorphix, errorphiy, errorphiz);
0449   }
0450 }
0451 
0452 //______________________________________________________________________________________________________
0453 void MuonScenarioBuilder::moveChamberInSector(Alignable* chamber,
0454                                               const align::Scalars& _disp,
0455                                               const align::Scalars& rotation,
0456                                               const align::Scalars& dispError,
0457                                               const align::Scalars& rotationError) {
0458   align::Scalars disp = _disp;
0459   align::RotationType rotx(Basic3DVector<double>(1.0, 0.0, 0.0), rotation[0]);
0460   align::RotationType roty(Basic3DVector<double>(0.0, 1.0, 0.0), rotation[1]);
0461   align::RotationType rotz(Basic3DVector<double>(0.0, 0.0, 1.0), rotation[2]);
0462   align::RotationType rot = rotz * roty * rotx;
0463   align::GlobalPoint pos = chamber->globalPosition();
0464   align::GlobalPoint dispRot(pos.basicVector() - rot * pos.basicVector());
0465   disp[0] += dispRot.x();
0466   disp[1] += dispRot.y();
0467   disp[2] += dispRot.z();
0468   theMuonModifier.moveAlignable(chamber, false, true, disp[0], disp[1], disp[2]);
0469   theMuonModifier.rotateAlignable(chamber, false, true, rotation[0], rotation[1], rotation[2]);
0470   theMuonModifier.addAlignmentPositionError(chamber, dispError[0], dispError[1], dispError[2]);
0471   theMuonModifier.addAlignmentPositionErrorFromRotation(chamber, rotationError[0], rotationError[1], rotationError[2]);
0472 }