File indexing completed on 2024-04-06 11:56:42
0001
0002
0003
0004
0005
0006
0007
0008 #include <string>
0009 #include <iostream>
0010 #include <sstream>
0011 #include <algorithm>
0012
0013
0014 #include "FWCore/Utilities/interface/Exception.h"
0015 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0016
0017
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 :
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
0039 theScenario = scenario;
0040 theModifierCounter = 0;
0041
0042
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
0049 const auto& dtBarrel = theAlignableMuon->DTBarrel();
0050 this->decodeMovements_(theScenario, dtBarrel, "DTBarrel");
0051
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') {
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
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);
0154 int counter = 0;
0155
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
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);
0245 std::fill_n(sector_index[0][0][0], 2 * 4 * 4 * 36, -1);
0246 int counter = 0;
0247
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
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
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
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
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
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 }