File indexing completed on 2024-04-06 11:58:33
0001
0002
0003
0004
0005
0006 #include "CalibPPS/AlignmentRelative/interface/IdealResult.h"
0007
0008 #include "CalibPPS/AlignmentRelative/interface/AlignmentTask.h"
0009
0010 #include "Geometry/Records/interface/VeryForwardRealGeometryRecord.h"
0011 #include "Geometry/Records/interface/VeryForwardMisalignedGeometryRecord.h"
0012
0013 #include "TMatrixD.h"
0014 #include "TVectorD.h"
0015
0016 using namespace std;
0017
0018
0019
0020 IdealResult::IdealResult(const edm::ParameterSet &gps, AlignmentTask *_t) : AlignmentAlgorithm(gps, _t) {}
0021
0022
0023
0024 void IdealResult::begin(const CTPPSGeometry *geometryReal, const CTPPSGeometry *geometryMisaligned) {
0025 gReal = geometryReal;
0026 gMisaligned = geometryMisaligned;
0027 }
0028
0029
0030 unsigned int IdealResult::solve(const std::vector<AlignmentConstraint> &constraints,
0031 std::map<unsigned int, AlignmentResult> &results,
0032 TDirectory *dir) {
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050 results.clear();
0051
0052
0053 unsigned int dim = 0;
0054 vector<unsigned int> offsets;
0055 map<unsigned int, unsigned int> offset_map;
0056 for (unsigned int qci = 0; qci < task->quantityClasses.size(); qci++) {
0057 offsets.push_back(dim);
0058 offset_map[task->quantityClasses[qci]] = dim;
0059 dim += task->quantitiesOfClass(task->quantityClasses[qci]);
0060 }
0061
0062
0063 TVectorD chi_tr(dim);
0064
0065 for (const auto &dit : task->geometry.getSensorMap()) {
0066 unsigned int detId = dit.first;
0067
0068 const DetGeomDesc *real = gReal->sensor(detId);
0069 const DetGeomDesc *misal = gMisaligned->sensor(detId);
0070
0071
0072 const auto shift = misal->translation() - real->translation();
0073
0074
0075 const auto rotation = misal->rotation() * real->rotation().Inverse();
0076
0077 double r_xx, r_xy, r_xz;
0078 double r_yx, r_yy, r_yz;
0079 double r_zx, r_zy, r_zz;
0080 rotation.GetComponents(r_xx, r_xy, r_xz, r_yx, r_yy, r_yz, r_zx, r_zy, r_zz);
0081
0082 if (std::abs(r_zz - 1.) > 1E-5)
0083 throw cms::Exception("PPS") << "IdealResult::Solve: only rotations about z are supported.";
0084
0085 double rot_z = atan2(r_yx, r_xx);
0086
0087 const auto &geom = task->geometry.get(detId);
0088
0089 for (unsigned int qci = 0; qci < task->quantityClasses.size(); ++qci) {
0090 const auto &qc = task->quantityClasses[qci];
0091 signed int idx = task->getQuantityIndex(qc, detId);
0092 if (idx < 0)
0093 continue;
0094
0095 double v = 0.;
0096
0097 if (qc == AlignmentTask::qcShR1) {
0098 const auto &d = geom.getDirectionData(1);
0099 v = shift.x() * d.dx + shift.y() * d.dy + shift.z() * d.dz;
0100 }
0101
0102 if (qc == AlignmentTask::qcShR2) {
0103 const auto &d = geom.getDirectionData(2);
0104 v = shift.x() * d.dx + shift.y() * d.dy + shift.z() * d.dz;
0105 }
0106
0107 if (qc == AlignmentTask::qcRotZ)
0108 v = rot_z;
0109
0110 chi_tr(offsets[qci] + idx) = v;
0111 }
0112 }
0113
0114
0115 vector<TVectorD> inaccessibleModes;
0116
0117 if (task->resolveShR) {
0118 TVectorD fm_ShX_gl(dim);
0119 fm_ShX_gl.Zero();
0120 TVectorD fm_ShX_lp(dim);
0121 fm_ShX_lp.Zero();
0122 TVectorD fm_ShY_gl(dim);
0123 fm_ShY_gl.Zero();
0124 TVectorD fm_ShY_lp(dim);
0125 fm_ShY_lp.Zero();
0126
0127 for (const auto &sp : task->geometry.getSensorMap()) {
0128 CTPPSDetId senId(sp.first);
0129 const auto &geom = sp.second;
0130
0131 if (senId.subdetId() == CTPPSDetId::sdTrackingStrip) {
0132 signed int qIndex = task->getQuantityIndex(AlignmentTask::qcShR2, senId);
0133
0134 const double d2x = geom.getDirectionData(2).dx;
0135 const double d2y = geom.getDirectionData(2).dy;
0136
0137 const auto &offset2 = offset_map[AlignmentTask::qcShR2];
0138 fm_ShX_gl(offset2 + qIndex) = d2x;
0139 fm_ShX_lp(offset2 + qIndex) = d2x * geom.z;
0140 fm_ShY_gl(offset2 + qIndex) = d2y;
0141 fm_ShY_lp(offset2 + qIndex) = d2y * geom.z;
0142 }
0143
0144 if (senId.subdetId() == CTPPSDetId::sdTrackingPixel) {
0145 const signed int qIndex1 = task->getQuantityIndex(AlignmentTask::qcShR1, senId);
0146 const signed int qIndex2 = task->getQuantityIndex(AlignmentTask::qcShR2, senId);
0147
0148 const double d1x = geom.getDirectionData(1).dx;
0149 const double d1y = geom.getDirectionData(1).dy;
0150 const double d2x = geom.getDirectionData(2).dx;
0151 const double d2y = geom.getDirectionData(2).dy;
0152
0153 const auto &offset1 = offset_map[AlignmentTask::qcShR1];
0154 fm_ShX_gl(offset1 + qIndex1) = d1x;
0155 fm_ShX_lp(offset1 + qIndex1) = d1x * geom.z;
0156 fm_ShY_gl(offset1 + qIndex1) = d1y;
0157 fm_ShY_lp(offset1 + qIndex1) = d1y * geom.z;
0158
0159 const auto &offset2 = offset_map[AlignmentTask::qcShR2];
0160 fm_ShX_gl(offset2 + qIndex2) = d2x;
0161 fm_ShX_lp(offset2 + qIndex2) = d2x * geom.z;
0162 fm_ShY_gl(offset2 + qIndex2) = d2y;
0163 fm_ShY_lp(offset2 + qIndex2) = d2y * geom.z;
0164 }
0165 }
0166
0167 inaccessibleModes.push_back(fm_ShX_gl);
0168 inaccessibleModes.push_back(fm_ShX_lp);
0169 inaccessibleModes.push_back(fm_ShY_gl);
0170 inaccessibleModes.push_back(fm_ShY_lp);
0171 }
0172
0173 if (task->resolveRotZ) {
0174 TVectorD fm_RotZ_gl(dim);
0175 fm_RotZ_gl.Zero();
0176 TVectorD fm_RotZ_lp(dim);
0177 fm_RotZ_lp.Zero();
0178
0179 for (const auto &sp : task->geometry.getSensorMap()) {
0180 CTPPSDetId senId(sp.first);
0181 const auto &geom = sp.second;
0182
0183 for (int m = 0; m < 2; ++m) {
0184 double rho = 0.;
0185 TVectorD *fmp = nullptr;
0186 if (m == 0) {
0187 rho = 1.;
0188 fmp = &fm_RotZ_gl;
0189 }
0190 if (m == 1) {
0191 rho = geom.z;
0192 fmp = &fm_RotZ_lp;
0193 }
0194 TVectorD &fm = *fmp;
0195
0196 const signed int qIndex = task->getQuantityIndex(AlignmentTask::qcRotZ, senId);
0197 const auto &offset = offset_map[AlignmentTask::qcRotZ];
0198 fm(offset + qIndex) = rho;
0199
0200 const double as_x = -rho * geom.sy;
0201 const double as_y = +rho * geom.sx;
0202
0203 if (senId.subdetId() == CTPPSDetId::sdTrackingStrip) {
0204 const double d2x = geom.getDirectionData(2).dx;
0205 const double d2y = geom.getDirectionData(2).dy;
0206
0207 const signed int qIndex2 = task->getQuantityIndex(AlignmentTask::qcShR2, senId);
0208 const auto &offset2 = offset_map[AlignmentTask::qcShR2];
0209 fm(offset2 + qIndex2) = d2x * as_x + d2y * as_y;
0210 }
0211
0212 if (senId.subdetId() == CTPPSDetId::sdTrackingPixel) {
0213 const double d1x = geom.getDirectionData(1).dx;
0214 const double d1y = geom.getDirectionData(1).dy;
0215 const double d2x = geom.getDirectionData(2).dx;
0216 const double d2y = geom.getDirectionData(2).dy;
0217
0218 const signed int qIndex1 = task->getQuantityIndex(AlignmentTask::qcShR1, senId);
0219 const auto &offset1 = offset_map[AlignmentTask::qcShR1];
0220 fm(offset1 + qIndex1) = d1x * as_x + d1y * as_y;
0221
0222 const signed int qIndex2 = task->getQuantityIndex(AlignmentTask::qcShR2, senId);
0223 const auto &offset2 = offset_map[AlignmentTask::qcShR2];
0224 fm(offset2 + qIndex2) = d2x * as_x + d2y * as_y;
0225 }
0226 }
0227 }
0228
0229 inaccessibleModes.push_back(fm_RotZ_gl);
0230 inaccessibleModes.push_back(fm_RotZ_lp);
0231 }
0232
0233
0234 TMatrixD C(dim, constraints.size());
0235 TVectorD V(constraints.size());
0236 for (unsigned int i = 0; i < constraints.size(); i++) {
0237 V(i) = constraints[i].val;
0238
0239 unsigned int offset = 0;
0240 for (auto &quantityClass : task->quantityClasses) {
0241 const TVectorD &cv = constraints[i].coef.find(quantityClass)->second;
0242 for (int k = 0; k < cv.GetNrows(); k++) {
0243 C[offset][i] = cv[k];
0244 offset++;
0245 }
0246 }
0247 }
0248
0249 TMatrixD I(dim, inaccessibleModes.size());
0250 for (unsigned int i = 0; i < inaccessibleModes.size(); ++i) {
0251 for (int j = 0; j < inaccessibleModes[i].GetNrows(); ++j)
0252 I(j, i) = inaccessibleModes[i](j);
0253 }
0254
0255
0256 TMatrixD CT(TMatrixD::kTransposed, C);
0257 TMatrixD CTI(CT * I);
0258
0259 const TMatrixD &A = CTI;
0260 TMatrixD AT(TMatrixD::kTransposed, A);
0261 TMatrixD ATA(AT * A);
0262 TMatrixD ATA_inv(TMatrixD::kInverted, ATA);
0263
0264 TVectorD b = V - CT * chi_tr;
0265
0266 TVectorD La(ATA_inv * AT * b);
0267
0268 TVectorD chi_exp(chi_tr + I * La);
0269
0270
0271 for (const auto &dit : task->geometry.getSensorMap()) {
0272 AlignmentResult r;
0273
0274 for (unsigned int qci = 0; qci < task->quantityClasses.size(); ++qci) {
0275 const auto &qc = task->quantityClasses[qci];
0276 const auto idx = task->getQuantityIndex(qc, dit.first);
0277 if (idx < 0)
0278 continue;
0279
0280 const auto &v = chi_exp(offsets[qci] + idx);
0281
0282 switch (qc) {
0283 case AlignmentTask::qcShR1:
0284 r.setShR1(v);
0285 break;
0286 case AlignmentTask::qcShR2:
0287 r.setShR2(v);
0288 break;
0289 case AlignmentTask::qcShZ:
0290 r.setShZ(v);
0291 break;
0292 case AlignmentTask::qcRotZ:
0293 r.setRotZ(v);
0294 break;
0295 }
0296 }
0297
0298 results[dit.first] = r;
0299 }
0300
0301 return 0;
0302 }