335 {
337
339
340
341 unsigned int nstrip = sfits.size();
342 if (nstrip < 3) {
344 if (nstrip == 2) {
345 Muon::CscTimeStatus tstatus = (sfits[0].charge > sfits[1].charge) ? sfits[0].timeStatus : sfits[1].timeStatus;
347 } else if (nstrip == 1) {
350 }
352 }
353
354
355 for (unsigned int istrip = 0; istrip < nstrip; ++istrip) {
356 if (sfits[istrip].
strip ==
nullptr) {
360 }
361 }
362
363
365 Identifier idStrip0 = pstrip->
identify();
366
367
369 const MuonGM::MuonDetectorManager* MuonDetMgr = DetectorManagerHandle.
cptr();
370 if (MuonDetMgr == nullptr) {
371 ATH_MSG_ERROR(
"Null pointer to the MuonDetectorManager conditions object");
373 }
375
376 bool measphi =
m_idHelperSvc->cscIdHelper().CscIdHelper::measuresPhi(idStrip0);
379 unsigned int strip0 =
m_idHelperSvc->cscIdHelper().strip(idStrip0) - 1;
380 int station =
m_idHelperSvc->cscIdHelper().stationName(idStrip0) - 49;
381
382 CscPlane plane = findPlane(station, measphi);
384 ATH_MSG_WARNING(
"Invalid CSC plane: station=" << station <<
"; measphi=" << measphi);
387 }
388
389
391 for (unsigned int istrip = 0; istrip < nstrip; ++istrip) {
392 Identifier id = sfits[istrip].strip->identify();
394 <<
m_idHelperSvc->cscIdHelper().strip(
id) <<
" " << sfits[istrip].charge);
395 }
396
397
398 unsigned int istrip_peak = 0;
399
400 for (unsigned int istrip = 1; istrip < nstrip - 1; ++istrip) {
401
404 float qthis = sfit.charge;
405 float qlast = sfits[istrip - 1].charge;
406 float qnext = sfits[istrip + 1].charge;
407
408 bool ispeak = qthis > qlast && qthis > qnext;
409
410
411
412 if (!ispeak) {
413 if (qthis == qnext) { ispeak = (qthis > qlast) && (istrip + 2 == nstrip || sfits[istrip + 2].
charge < qthis); }
414 }
415
416
417 if (!ispeak) {
418 if (istrip == 1) {
419 if (qthis == qlast) {
420 ispeak = qthis > qnext;
421 }
422 }
423 }
424
425 if (ispeak) {
426 if (istrip_peak) {
429 }
430 istrip_peak = istrip;
431 }
432 }
433 ATH_MSG_VERBOSE(
" Peak is at " << istrip_peak <<
"th strip in cluster");
434
435
436 if (strip0 <= 0 || strip0 + nstrip > maxstrip) {
439 }
440
441
442
443
444
445
446
447
448
449
450
451
452 bool is_even = 2 * (nstrip / 2) == nstrip;
453 bool atcenter = istrip_peak == nstrip / 2 || (is_even && istrip_peak + 1 == nstrip / 2);
454 if (!atcenter) {
457 }
458
463 }
464
465
467
468
469 ) {
476 }
477
479
480 double savg = istrip_peak;
481
482
485 double dpos = 0.0;
486 if (measphi) {
489 }
490 double q1 = sfits[istrip_peak - 1].charge;
491 double q0 = sfits[istrip_peak].charge;
492 double q2 = sfits[istrip_peak + 1].charge;
493 double qrat1 = q1 / q0;
494 double qrat2 = q2 / q0;
495 double dq1 = sfits[istrip_peak - 1].dcharge;
496 double dq0 = sfits[istrip_peak].dcharge;
497 double dq2 = sfits[istrip_peak + 1].dcharge;
498
500 double scor1 = 0.;
501 double dscordqrat1 = 0.;
502 double scor2 = 0;
503 double dscordqrat2 = 0.;
504 int stat1 = 0;
505 int stat2 = 0;
506 if (posopt == "POLYNOMIAL") {
509 } else if (posopt == "TABLE") {
510 double qrmin = 0.0;
511 const std::vector<double>* pcor = nullptr;
518 } else {
522 }
523 if (pcor) {
526 } else {
527 stat1 = 99;
528 }
529 } else if (posopt == "ATANH") {
541 } else {
545 }
546 stat1 =
qrat_atanh(
a, b, c, x0, qrat1, scor1, dscordqrat1);
547 stat2 =
qrat_atanh(
a, b, c, x0, qrat2, scor2, dscordqrat2);
548
549 } else {
553 }
554 if (stat1 || stat2) {
558 }
560 ATH_MSG_VERBOSE(
" QRAT derivatives: " << dscordqrat1 <<
" " << dscordqrat2);
561
562
563
564 scor1 = -scor1;
565 dscordqrat1 = -dscordqrat1;
566 double scor = 0.0;
568
569
570 if (erropt == "FIXED") {
571 double w1 = 1 / (dscordqrat1 * dscordqrat1);
572 double w2 = 1 / (dscordqrat2 * dscordqrat2);
573 scor = (w1 * scor1 + w2 * scor2) / (w1 + w2);
574 double scor_diff = std::abs(scor2 - scor1);
577
578 dmap["scor1"] = scor1;
579 dmap["scor2"] = scor2;
580 dmap["scor"] = scor;
581
586 }
587
588 } else if (erropt == "CHARGE") {
589
590 double x1 = dscordqrat1 * qrat1;
591 double x2 = dscordqrat2 * qrat2;
592 double dqq0 = dq0 / q0;
593 double dqq1 = dq1 / q1;
594 double dqq2 = dq2 / q2;
595 double rnum = (-
x1 *
x1 * dqq1 * dqq1 +
x2 *
x2 * dqq2 * dqq2 + (
x2 *
x2 -
x1 *
x1) * dqq0 * dqq0);
596 double rden = (
x1 *
x1 * dqq1 * dqq1 +
x2 *
x2 * dqq2 * dqq2 + (
x2 -
x1) * (
x2 -
x1) * dqq0 * dqq0);
597 double rfac = rnum / rden;
598
599 double dscor_diff = sqrt(rden);
600 double scor_diff = scor2 - scor1;
601 double scor_sig = std::abs(scor_diff) / dscor_diff;
602
603 double w1 = 0.5 * (1.0 +
rfac);
604 double w2 = 0.5 * (1.0 -
rfac);
605 scor = w1 * scor1 + w2 * scor2;
606
607 double ddscor1 = w1 *
x1 * dqq1;
608 double ddscor2 = w2 *
x2 * dqq2;
609 double ddscor0 = (w1 *
x1 + w2 *
x2) * dqq0;
610 double dscor = sqrt(ddscor1 * ddscor1 + ddscor2 * ddscor2 + ddscor0 * ddscor0);
611 dpos = pitch * dscor;
612
614
615 double dscor1 = std::abs(x1) * sqrt(dqq1 * dqq1 + dqq0 * dqq0);
616 double dscor2 = std::abs(x2) * sqrt(dqq2 * dqq2 + dqq0 * dqq0);
617 dmap["scor1"] = scor1;
618 dmap["dscor1"] = dscor1;
619 dmap["scor2"] = scor2;
620 dmap["dscor2"] = dscor2;
621 dmap["scordiff"] = scor_diff;
622 dmap["dscordiff"] = dscor_diff;
623 dmap["scor"] = scor;
624 dmap["dscor"] = dscor;
625
628 ATH_MSG_VERBOSE(
" dq1, dq0, dq2: " << dq1 <<
" " << dq0 <<
" " << dq2);
636
637
642 }
643 } else {
647 }
648
649
650 savg += scor + strip0;
651 ATH_MSG_VERBOSE(
" QRAT corr " << splane(plane) <<
" nstrip=" << nstrip <<
" savg=" << savg <<
" qrat1=" << qrat1
652 << " qrat2=" << qrat2 << " scor1=" << scor1 << " scor2=" << scor2);
653
654
656
657
659
660
662 res.strip = istrip_peak;
663 res.position = pitch * (savg + 0.5 - 0.5 * maxstrip);
664
665
666 Identifier
id = sfits[
res.strip].strip->identify();
669
670 res.dposition = sqrt(dpos * dpos + dpostht * dpostht);
671
673 res.lstrip = nstrip - 1;
674 res.time = sfits[istrip_peak].time;
675 res.time_beforeT0Corr = sfits[istrip_peak].time_beforeT0Corr;
676 res.time_beforeBPCorr = sfits[istrip_peak].time_beforeBPCorr;
677 res.timeStatus = sfits[istrip_peak].timeStatus;
678
682
683
684
685
686
688 res.charge_beforeBPCorr =
689 sfits[istrip_peak].charge_beforeBPCorr + sfits[istrip_peak - 1].charge_beforeBPCorr + sfits[istrip_peak + 1].charge_beforeBPCorr;
690
692
693 ATH_MSG_VERBOSE(
" Position :: pos=" <<
res.position <<
" dpos:dtht=" << dpos <<
":" << dpostht <<
" ==>" <<
res.dposition
694 << " at tanth=" << tantheta);
695
698}
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
double charge(const T &p)
int qrat_correction(CscPlane plane, double qrat, double &cor, double &dcordqrat)
int qrat_atanh(const double a, const double b, double c, const double x0, double qrat, double &cor, double &dcordqrat)
Calculate QRAT correction from inverse hyperbolic tangent based on a fit to the plot of pos x vs char...
int qrat_interpolation(double qrmin, const std::vector< double > &corvals, double qrat, double &cor, double &dcordqrat)
ICscStripFitter::Result StripFit
std::map< std::string, double > DataMap
double cathodeReadoutPitch(int chLayer, int measuresPhi) const
int maxNumberOfStrips(int measuresPhi) const
const CscReadoutElement * getCscReadoutElement(const Identifier &id) const
access via extended identifier (requires unpacking)
SG::ReadCondHandleKey< MuonGM::MuonDetectorManager > m_DetectorManagerKey
retrieve MuonDetectorManager from the conditions store
ToolHandle< ICscAlignmentTool > m_alignmentTool
const_pointer_type cptr()
rfac(flags, cells_name, *args, **kw)
@ CscStatusUnspoiled
Clean cluster with precision fit.
@ CscStatusStripFitFailed
@ CscStatusUndefined
Undefined, should not happen, most likely indicates a problem.
@ CscStatusSkewed
Skewed, e.g.
@ CscStatusEdge
Cluster reaches the edge of plane.
@ CscStatusMultiPeak
More than one peak in cluster.
@ CscStatusQratInconsistent
Positions from Qrat_left and Qrat_right is not consistent.
@ CscStatusNarrow
Too narrow.
CscTimeStatus
Enum to represent the cluster time measurement status - see the specific enum values for more details...
#define CXXUTILS_TRAPPING_FP