File indexing completed on 2024-04-06 12:28:06
0001 #include "FWCore/Framework/interface/ConsumesCollector.h"
0002 #include "FWCore/Framework/interface/ESHandle.h"
0003
0004 #include "RecoTracker/DeDx/interface/DeDxTools.h"
0005
0006 #include <vector>
0007 #include <numeric>
0008
0009 namespace deDxTools {
0010 using namespace std;
0011 using namespace reco;
0012
0013 bool shapeSelection(const SiStripCluster& clus) {
0014
0015
0016 auto const& ampls = clus.amplitudes();
0017 Int_t NofMax = 0;
0018 Int_t recur255 = 1;
0019 Int_t recur254 = 1;
0020 bool MaxOnStart = false;
0021 bool MaxInMiddle = false, MaxOnEnd = false;
0022 Int_t MaxPos = 0;
0023
0024
0025 if (ampls.size() != 1 &&
0026 ((ampls[0] > ampls[1]) ||
0027 (ampls.size() > 2 && ampls[0] == ampls[1] && ampls[1] > ampls[2] && ampls[0] != 254 && ampls[0] != 255) ||
0028 (ampls.size() == 2 && ampls[0] == ampls[1] && ampls[0] != 254 && ampls[0] != 255))) {
0029 NofMax = NofMax + 1;
0030 MaxOnStart = true;
0031 }
0032
0033
0034 if (ampls.size() > 2) {
0035 for (unsigned int i = 1; i < ampls.size() - 1U; i++) {
0036 if ((ampls[i] > ampls[i - 1] && ampls[i] > ampls[i + 1]) ||
0037 (ampls.size() > 3 && i > 0 && i < ampls.size() - 2U && ampls[i] == ampls[i + 1] &&
0038 ampls[i] > ampls[i - 1] && ampls[i] > ampls[i + 2] && ampls[i] != 254 && ampls[i] != 255)) {
0039 NofMax = NofMax + 1;
0040 MaxInMiddle = true;
0041 MaxPos = i;
0042 }
0043 if (ampls[i] == 255 && ampls[i] == ampls[i - 1]) {
0044 recur255 = recur255 + 1;
0045 MaxPos = i - (recur255 / 2);
0046 if (ampls[i] > ampls[i + 1]) {
0047 NofMax = NofMax + 1;
0048 MaxInMiddle = true;
0049 }
0050 }
0051 if (ampls[i] == 254 && ampls[i] == ampls[i - 1]) {
0052 recur254 = recur254 + 1;
0053 MaxPos = i - (recur254 / 2);
0054 if (ampls[i] > ampls[i + 1]) {
0055 NofMax = NofMax + 1;
0056 MaxInMiddle = true;
0057 }
0058 }
0059 }
0060 }
0061
0062
0063 if (ampls.size() > 1) {
0064 if (ampls[ampls.size() - 1] > ampls[ampls.size() - 2] ||
0065 (ampls.size() > 2 && ampls[ampls.size() - 1] == ampls[ampls.size() - 2] &&
0066 ampls[ampls.size() - 2] > ampls[ampls.size() - 3]) ||
0067 ampls[ampls.size() - 1] == 255) {
0068 NofMax = NofMax + 1;
0069 MaxOnEnd = true;
0070 }
0071 }
0072
0073
0074 if (ampls.size() == 1) {
0075 NofMax = 1;
0076 }
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090 bool shapecdtn = false;
0091
0092 Float_t C_M = 0.0;
0093 Float_t C_D = 0.0;
0094 Float_t C_Mn = 10000;
0095 Float_t C_Dn = 10000;
0096 Float_t C_Mnn = 10000;
0097 Float_t C_Dnn = 10000;
0098 Int_t CDPos;
0099 Float_t coeff1 = 1.7;
0100 Float_t coeff2 = 2.0;
0101 Float_t coeffn = 0.10;
0102 Float_t coeffnn = 0.02;
0103 Float_t noise = 4.0;
0104
0105 if (NofMax == 1) {
0106 if (MaxOnStart == true) {
0107 C_M = (Float_t)ampls[0];
0108 C_D = (Float_t)ampls[1];
0109 if (ampls.size() < 3)
0110 shapecdtn = true;
0111 else if (ampls.size() == 3) {
0112 C_Dn = (Float_t)ampls[2];
0113 if (C_Dn <= coeff1 * coeffn * C_D + coeff2 * coeffnn * C_M + 2 * noise || C_D == 255)
0114 shapecdtn = true;
0115 } else if (ampls.size() > 3) {
0116 C_Dn = (Float_t)ampls[2];
0117 C_Dnn = (Float_t)ampls[3];
0118 if ((C_Dn <= coeff1 * coeffn * C_D + coeff2 * coeffnn * C_M + 2 * noise || C_D == 255) &&
0119 C_Dnn <= coeff1 * coeffn * C_Dn + coeff2 * coeffnn * C_D + 2 * noise) {
0120 shapecdtn = true;
0121 }
0122 }
0123 }
0124
0125 if (MaxOnEnd == true) {
0126 C_M = (Float_t)ampls[ampls.size() - 1];
0127 C_D = (Float_t)ampls[ampls.size() - 2];
0128 if (ampls.size() < 3)
0129 shapecdtn = true;
0130 else if (ampls.size() == 3) {
0131 C_Dn = (Float_t)ampls[0];
0132 if (C_Dn <= coeff1 * coeffn * C_D + coeff2 * coeffnn * C_M + 2 * noise || C_D == 255)
0133 shapecdtn = true;
0134 } else if (ampls.size() > 3) {
0135 C_Dn = (Float_t)ampls[ampls.size() - 3];
0136 C_Dnn = (Float_t)ampls[ampls.size() - 4];
0137 if ((C_Dn <= coeff1 * coeffn * C_D + coeff2 * coeffnn * C_M + 2 * noise || C_D == 255) &&
0138 C_Dnn <= coeff1 * coeffn * C_Dn + coeff2 * coeffnn * C_D + 2 * noise) {
0139 shapecdtn = true;
0140 }
0141 }
0142 }
0143
0144 if (MaxInMiddle == true) {
0145 C_M = (Float_t)ampls[MaxPos];
0146 int LeftOfMaxPos = MaxPos - 1;
0147 if (LeftOfMaxPos <= 0)
0148 LeftOfMaxPos = 0;
0149 int RightOfMaxPos = MaxPos + 1;
0150 if (RightOfMaxPos >= (int)ampls.size())
0151 RightOfMaxPos = ampls.size() - 1;
0152 if (ampls[LeftOfMaxPos] < ampls[RightOfMaxPos]) {
0153 C_D = (Float_t)ampls[RightOfMaxPos];
0154 C_Mn = (Float_t)ampls[LeftOfMaxPos];
0155 CDPos = RightOfMaxPos;
0156 } else {
0157 C_D = (Float_t)ampls[LeftOfMaxPos];
0158 C_Mn = (Float_t)ampls[RightOfMaxPos];
0159 CDPos = LeftOfMaxPos;
0160 }
0161 if (C_Mn < coeff1 * coeffn * C_M + coeff2 * coeffnn * C_D + 2 * noise || C_M == 255) {
0162 if (ampls.size() == 3)
0163 shapecdtn = true;
0164 else if (ampls.size() > 3) {
0165 if (CDPos > MaxPos) {
0166 if (ampls.size() - CDPos - 1 == 0) {
0167 C_Dn = 0;
0168 C_Dnn = 0;
0169 }
0170 if (ampls.size() - CDPos - 1 == 1) {
0171 C_Dn = (Float_t)ampls[CDPos + 1];
0172 C_Dnn = 0;
0173 }
0174 if (ampls.size() - CDPos - 1 > 1) {
0175 C_Dn = (Float_t)ampls[CDPos + 1];
0176 C_Dnn = (Float_t)ampls[CDPos + 2];
0177 }
0178 if (MaxPos >= 2) {
0179 C_Mnn = (Float_t)ampls[MaxPos - 2];
0180 } else if (MaxPos < 2)
0181 C_Mnn = 0;
0182 }
0183 if (CDPos < MaxPos) {
0184 if (CDPos == 0) {
0185 C_Dn = 0;
0186 C_Dnn = 0;
0187 }
0188 if (CDPos == 1) {
0189 C_Dn = (Float_t)ampls[0];
0190 C_Dnn = 0;
0191 }
0192 if (CDPos > 1) {
0193 C_Dn = (Float_t)ampls[CDPos - 1];
0194 C_Dnn = (Float_t)ampls[CDPos - 2];
0195 }
0196 if (ampls.size() - LeftOfMaxPos > 1 && MaxPos + 2 < (int)(ampls.size()) - 1) {
0197 C_Mnn = (Float_t)ampls[MaxPos + 2];
0198 } else
0199 C_Mnn = 0;
0200 }
0201 if ((C_Dn <= coeff1 * coeffn * C_D + coeff2 * coeffnn * C_M + 2 * noise || C_D == 255) &&
0202 C_Mnn <= coeff1 * coeffn * C_Mn + coeff2 * coeffnn * C_M + 2 * noise &&
0203 C_Dnn <= coeff1 * coeffn * C_Dn + coeff2 * coeffnn * C_D + 2 * noise) {
0204 shapecdtn = true;
0205 }
0206 }
0207 }
0208 }
0209 }
0210 if (ampls.size() == 1) {
0211 shapecdtn = true;
0212 }
0213
0214 return shapecdtn;
0215 }
0216
0217 int getCharge(const SiStripCluster* cluster,
0218 int& nSatStrip,
0219 const GeomDetUnit& detUnit,
0220 const std::vector<std::vector<float> >& calibGains,
0221 const unsigned int& offsetDU_) {
0222 const auto& Ampls = cluster->amplitudes();
0223
0224 nSatStrip = 0;
0225 int charge = 0;
0226
0227 if (calibGains.empty()) {
0228 for (unsigned int i = 0; i < Ampls.size(); i++) {
0229 int calibratedCharge = Ampls[i];
0230 charge += calibratedCharge;
0231 if (calibratedCharge >= 254)
0232 nSatStrip++;
0233 }
0234 } else {
0235 for (unsigned int i = 0; i < Ampls.size(); i++) {
0236 int calibratedCharge = Ampls[i];
0237
0238 auto& gains = calibGains[detUnit.index() - offsetDU_];
0239 calibratedCharge = (int)(calibratedCharge / gains[(cluster->firstStrip() + i) / 128]);
0240 if (calibratedCharge >= 255) {
0241 if (calibratedCharge >= 1025)
0242 calibratedCharge = 255;
0243 else
0244 calibratedCharge = 254;
0245 }
0246
0247 charge += calibratedCharge;
0248 if (calibratedCharge >= 254)
0249 nSatStrip++;
0250 }
0251 }
0252 return charge;
0253 }
0254
0255 void makeCalibrationMap(const std::string& m_calibrationPath,
0256 const TrackerGeometry& tkGeom,
0257 std::vector<std::vector<float> >& calibGains,
0258 const unsigned int& offsetDU_) {
0259 auto const& dus = tkGeom.detUnits();
0260 calibGains.resize(dus.size() - offsetDU_);
0261
0262 TChain* t1 = new TChain("SiStripCalib/APVGain");
0263 t1->Add(m_calibrationPath.c_str());
0264
0265 unsigned int tree_DetId;
0266 unsigned char tree_APVId;
0267 double tree_Gain;
0268 t1->SetBranchAddress("DetId", &tree_DetId);
0269 t1->SetBranchAddress("APVId", &tree_APVId);
0270 t1->SetBranchAddress("Gain", &tree_Gain);
0271
0272 for (unsigned int ientry = 0; ientry < t1->GetEntries(); ientry++) {
0273 t1->GetEntry(ientry);
0274 auto& gains = calibGains[tkGeom.idToDetUnit(DetId(tree_DetId))->index() - offsetDU_];
0275 if (gains.size() < (size_t)(tree_APVId + 1)) {
0276 gains.resize(tree_APVId + 1);
0277 }
0278 gains[tree_APVId] = tree_Gain;
0279 }
0280 t1->Delete();
0281 }
0282
0283 ESGetTokenH3DDVariant esConsumes(std::string const& Record, edm::ConsumesCollector& iCC) {
0284 if (Record == "SiStripDeDxMip_3D_Rcd") {
0285 return iCC.esConsumes<H3DD, SiStripDeDxMip_3D_Rcd, edm::Transition::BeginRun>();
0286 }
0287 if (Record == "SiStripDeDxPion_3D_Rcd") {
0288 return iCC.esConsumes<H3DD, SiStripDeDxPion_3D_Rcd, edm::Transition::BeginRun>();
0289 }
0290 if (Record == "SiStripDeDxKaon_3D_Rcd") {
0291 return iCC.esConsumes<H3DD, SiStripDeDxKaon_3D_Rcd, edm::Transition::BeginRun>();
0292 }
0293 if (Record == "SiStripDeDxProton_3D_Rcd") {
0294 return iCC.esConsumes<H3DD, SiStripDeDxProton_3D_Rcd, edm::Transition::BeginRun>();
0295 }
0296 if (Record == "SiStripDeDxElectron_3D_Rcd") {
0297 return iCC.esConsumes<H3DD, SiStripDeDxElectron_3D_Rcd, edm::Transition::BeginRun>();
0298 }
0299 throw cms::Exception("WrongRecord for dEdx") << "The record : " << Record << "is unknown\n";
0300 }
0301
0302 PhysicsTools::Calibration::HistogramD3D const& getHistogramD3D(edm::EventSetup const& iES,
0303 ESGetTokenH3DDVariant const& iToken) {
0304 switch (iToken.index()) {
0305 case 0:
0306 return iES.getData(std::get<0>(iToken));
0307 case 1:
0308 return iES.getData(std::get<1>(iToken));
0309 case 2:
0310 return iES.getData(std::get<2>(iToken));
0311 case 3:
0312 return iES.getData(std::get<3>(iToken));
0313 case 4:
0314 return iES.getData(std::get<4>(iToken));
0315 }
0316 throw cms::Exception("HistogramD3DTokenUnset");
0317 }
0318
0319 void buildDiscrimMap(PhysicsTools::Calibration::HistogramD3D const& deDxMap,
0320 std::string const& ProbabilityMode,
0321 TH3F*& Prob_ChargePath) {
0322 float xmin = deDxMap.rangeX().min;
0323 float xmax = deDxMap.rangeX().max;
0324 float ymin = deDxMap.rangeY().min;
0325 float ymax = deDxMap.rangeY().max;
0326 float zmin = deDxMap.rangeZ().min;
0327 float zmax = deDxMap.rangeZ().max;
0328
0329 if (Prob_ChargePath)
0330 delete Prob_ChargePath;
0331 Prob_ChargePath = new TH3F("Prob_ChargePath",
0332 "Prob_ChargePath",
0333 deDxMap.numberOfBinsX(),
0334 xmin,
0335 xmax,
0336 deDxMap.numberOfBinsY(),
0337 ymin,
0338 ymax,
0339 deDxMap.numberOfBinsZ(),
0340 zmin,
0341 zmax);
0342
0343 if (strcmp(ProbabilityMode.c_str(), "Accumulation") == 0) {
0344 for (int i = 0; i <= Prob_ChargePath->GetXaxis()->GetNbins() + 1; i++) {
0345 for (int j = 0; j <= Prob_ChargePath->GetYaxis()->GetNbins() + 1; j++) {
0346 float Ni = 0;
0347 for (int k = 0; k <= Prob_ChargePath->GetZaxis()->GetNbins() + 1; k++) {
0348 Ni += deDxMap.binContent(i, j, k);
0349 }
0350 for (int k = 0; k <= Prob_ChargePath->GetZaxis()->GetNbins() + 1; k++) {
0351 float tmp = 0;
0352 for (int l = 0; l <= k; l++) {
0353 tmp += deDxMap.binContent(i, j, l);
0354 }
0355 if (Ni > 0) {
0356 Prob_ChargePath->SetBinContent(i, j, k, tmp / Ni);
0357 } else {
0358 Prob_ChargePath->SetBinContent(i, j, k, 0);
0359 }
0360 }
0361 }
0362 }
0363 } else if (strcmp(ProbabilityMode.c_str(), "Integral") == 0) {
0364 for (int i = 0; i <= Prob_ChargePath->GetXaxis()->GetNbins() + 1; i++) {
0365 for (int j = 0; j <= Prob_ChargePath->GetYaxis()->GetNbins() + 1; j++) {
0366 float Ni = 0;
0367 for (int k = 0; k <= Prob_ChargePath->GetZaxis()->GetNbins() + 1; k++) {
0368 Ni += deDxMap.binContent(i, j, k);
0369 }
0370 for (int k = 0; k <= Prob_ChargePath->GetZaxis()->GetNbins() + 1; k++) {
0371 float tmp = deDxMap.binContent(i, j, k);
0372 if (Ni > 0) {
0373 Prob_ChargePath->SetBinContent(i, j, k, tmp / Ni);
0374 } else {
0375 Prob_ChargePath->SetBinContent(i, j, k, 0);
0376 }
0377 }
0378 }
0379 }
0380 } else {
0381 throw cms::Exception("WrongConfig for dEdx") << "The ProbabilityMode: " << ProbabilityMode << "is unknown\n";
0382 }
0383 }
0384
0385 bool isSpanningOver2APV(unsigned int FirstStrip, unsigned int ClusterSize) {
0386 if (FirstStrip == 0)
0387 return true;
0388 if (FirstStrip == 128)
0389 return true;
0390 if (FirstStrip == 256)
0391 return true;
0392 if (FirstStrip == 384)
0393 return true;
0394 if (FirstStrip == 512)
0395 return true;
0396 if (FirstStrip == 640)
0397 return true;
0398
0399 if (FirstStrip <= 127 && FirstStrip + ClusterSize > 127)
0400 return true;
0401 if (FirstStrip <= 255 && FirstStrip + ClusterSize > 255)
0402 return true;
0403 if (FirstStrip <= 383 && FirstStrip + ClusterSize > 383)
0404 return true;
0405 if (FirstStrip <= 511 && FirstStrip + ClusterSize > 511)
0406 return true;
0407 if (FirstStrip <= 639 && FirstStrip + ClusterSize > 639)
0408 return true;
0409
0410 if (FirstStrip + ClusterSize == 127)
0411 return true;
0412 if (FirstStrip + ClusterSize == 255)
0413 return true;
0414 if (FirstStrip + ClusterSize == 383)
0415 return true;
0416 if (FirstStrip + ClusterSize == 511)
0417 return true;
0418 if (FirstStrip + ClusterSize == 639)
0419 return true;
0420 if (FirstStrip + ClusterSize == 767)
0421 return true;
0422
0423 return false;
0424 }
0425
0426 bool isFarFromBorder(const TrajectoryStateOnSurface& trajState, const GeomDetUnit* it) {
0427 if (dynamic_cast<const StripGeomDetUnit*>(it) == nullptr && dynamic_cast<const PixelGeomDetUnit*>(it) == nullptr) {
0428 edm::LogInfo("deDxTools") << "this detID doesn't seem to belong to the Tracker" << std::endl;
0429 return false;
0430 }
0431
0432 LocalPoint HitLocalPos = trajState.localPosition();
0433 LocalError HitLocalError = trajState.localError().positionError();
0434
0435 const BoundPlane plane = it->surface();
0436 const TrapezoidalPlaneBounds* trapezoidalBounds(dynamic_cast<const TrapezoidalPlaneBounds*>(&(plane.bounds())));
0437 const RectangularPlaneBounds* rectangularBounds(dynamic_cast<const RectangularPlaneBounds*>(&(plane.bounds())));
0438
0439 if (!trapezoidalBounds && !rectangularBounds)
0440 return false;
0441
0442 double DistFromBorder = 1.0;
0443 double HalfLength =
0444 trapezoidalBounds ? (*trapezoidalBounds).parameters()[3] : it->surface().bounds().length() / 2.0;
0445
0446 if (fabs(HitLocalPos.y()) + HitLocalError.yy() >= (HalfLength - DistFromBorder))
0447 return false;
0448
0449 return true;
0450 }
0451
0452 }