40 return "no such plane";
43 CscPlane findPlane(
int station,
bool measphi) {
49 }
else if (station == 2) {
62 std::vector<double> pfac;
64 if (qrat < 0.095)
return 1;
65 if (qrat > 1.01)
return 1;
67 pfac.push_back(-5.483);
68 pfac.push_back(130.6);
69 pfac.push_back(-1296.);
70 pfac.push_back(5994.);
71 pfac.push_back(-10580.);
72 }
else if (qrat < 0.30) {
73 pfac.push_back(-0.9225);
74 pfac.push_back(5.569);
75 pfac.push_back(2.908);
76 pfac.push_back(-66.19);
77 pfac.push_back(108.5);
79 pfac.push_back(-0.4246);
80 pfac.push_back(2.619);
81 pfac.push_back(-3.642);
82 pfac.push_back(2.837);
83 pfac.push_back(-0.8916);
86 if (qrat < 0.105)
return 1;
87 if (qrat > 1.01)
return 1;
89 pfac.push_back(-2.823);
90 pfac.push_back(42.71);
91 pfac.push_back(-279.1);
92 pfac.push_back(879.2);
93 pfac.push_back(-1062.);
95 pfac.push_back(-0.5409);
96 pfac.push_back(3.110);
97 pfac.push_back(-4.630);
98 pfac.push_back(3.800);
99 pfac.push_back(-1.241);
107 for (
unsigned int ipow = 0; ipow < pfac.size(); ++ipow) {
108 dcordqrat += ipow * pfac[ipow] * term;
109 if (ipow) term *= qrat;
110 cor += pfac[ipow] * term;
127 int qrat_interpolation(
double qrmin,
const std::vector<double>& corvals,
double qrat,
double& cor,
double& dcordqrat) {
128 int nbin = corvals.size();
131 if (qrat < qrmin) qrat = qrmin;
133 double dqrat = 1.0 / nbin;
134 int bin =
int(qrat / dqrat);
137 double x1 = corvals[
bin];
138 if (
x1 == 0.0)
return 2;
139 double x0 =
bin == 0 ? 0.0 : corvals[
bin - 1];
140 double x2 =
bin == nbin - 1 ? 1.0 : corvals[
bin + 1];
143 double qrat0 = dqrat *
bin;
144 double qrat1 = qrat0 + dqrat;
147 if (qrmin > qrat0 && qrmin < qrat1) { qrat0 = qrmin; }
153 if (
bin == nbin - 1) {
155 double b = (
x1 - x0) / dqrat;
156 cor =
a +
b * (qrat - qrat0);
159 double d0 = qrat1 - qrat0;
165 cor =
a +
b * (qrat - qrat1) +
c * (qrat - qrat1) * (qrat - qrat1);
166 dcordqrat =
b + 2.0 *
c * (qrat - qrat1);
168 if (cor < 0.0) cor = 0.0;
193 int qrat_atanh(
const double a,
const double b,
double c,
const double x0,
double qrat,
double& cor,
double& dcordqrat) {
194 if (qrat <= 0)
return 1;
196 double qrmin =
a +
b * tanh(
c * (-1 - x0));
199 if (qrat < qrmin) qrat = qrmin;
200 double z = (qrat -
a) /
b;
201 cor = atanh(
z) /
c + x0;
202 dcordqrat = 1.0 / (1.0 -
z *
z) /
b /
c;
211 declareInterface<ICscClusterFitter>(
this);
296 return StatusCode::SUCCESS;
304 bool dofixed =
false;
305 bool docharge =
false;
314 if (dofixed || docharge) {
315 dnames.emplace_back(
"scor1");
316 dnames.emplace_back(
"scor2");
317 dnames.emplace_back(
"scor");
320 dnames.emplace_back(
"dscor1");
321 dnames.emplace_back(
"dscor2");
322 dnames.emplace_back(
"dscor");
323 dnames.emplace_back(
"scordiff");
324 dnames.emplace_back(
"dscordiff");
340 unsigned int nstrip = sfits.size();
344 Muon::CscTimeStatus tstatus = (sfits[0].charge > sfits[1].charge) ? sfits[0].timeStatus : sfits[1].timeStatus;
346 }
else if (nstrip == 1) {
354 for (
unsigned int istrip = 0; istrip < nstrip; ++istrip) {
355 if (sfits[istrip].
strip ==
nullptr) {
369 if (MuonDetMgr ==
nullptr) {
370 ATH_MSG_ERROR(
"Null pointer to the MuonDetectorManager conditions object");
375 bool measphi =
m_idHelperSvc->cscIdHelper().CscIdHelper::measuresPhi(idStrip0);
378 unsigned int strip0 =
m_idHelperSvc->cscIdHelper().strip(idStrip0) - 1;
379 int station =
m_idHelperSvc->cscIdHelper().stationName(idStrip0) - 49;
381 CscPlane plane = findPlane(station, measphi);
383 ATH_MSG_WARNING(
"Invalid CSC plane: station=" << station <<
"; measphi=" << measphi);
390 for (
unsigned int istrip = 0; istrip < nstrip; ++istrip) {
391 Identifier id = sfits[istrip].strip->identify();
393 <<
m_idHelperSvc->cscIdHelper().strip(
id) <<
" " << sfits[istrip].charge);
397 unsigned int istrip_peak = 0;
399 for (
unsigned int istrip = 1; istrip < nstrip - 1; ++istrip) {
401 float qthis = sfit.
charge;
402 float qlast = sfits[istrip - 1].charge;
403 float qnext = sfits[istrip + 1].charge;
405 bool ispeak = qthis > qlast && qthis > qnext;
410 if (qthis == qnext) { ispeak = (qthis > qlast) && (istrip + 2 == nstrip || sfits[istrip + 2].
charge < qthis); }
416 if (qthis == qlast) {
417 ispeak = qthis > qnext;
427 istrip_peak = istrip;
430 ATH_MSG_VERBOSE(
" Peak is at " << istrip_peak <<
"th strip in cluster");
433 if (strip0 <= 0 || strip0 + nstrip > maxstrip) {
449 bool is_even = 2 * (nstrip / 2) == nstrip;
450 bool atcenter = istrip_peak == nstrip / 2 || (is_even && istrip_peak + 1 == nstrip / 2);
477 double savg = istrip_peak;
487 double q1 = sfits[istrip_peak - 1].charge;
488 double q0 = sfits[istrip_peak].charge;
489 double q2 = sfits[istrip_peak + 1].charge;
490 double qrat1 = q1 / q0;
491 double qrat2 = q2 / q0;
492 double dq1 = sfits[istrip_peak - 1].dcharge;
493 double dq0 = sfits[istrip_peak].dcharge;
494 double dq2 = sfits[istrip_peak + 1].dcharge;
498 double dscordqrat1 = 0.;
500 double dscordqrat2 = 0.;
503 if (posopt ==
"POLYNOMIAL") {
506 }
else if (posopt ==
"TABLE") {
508 const std::vector<double>* pcor =
nullptr;
526 }
else if (posopt ==
"ATANH") {
551 if (stat1 || stat2) {
557 ATH_MSG_VERBOSE(
" QRAT derivatives: " << dscordqrat1 <<
" " << dscordqrat2);
562 dscordqrat1 = -dscordqrat1;
567 if (erropt ==
"FIXED") {
568 double w1 = 1 / (dscordqrat1 * dscordqrat1);
569 double w2 = 1 / (dscordqrat2 * dscordqrat2);
570 scor = (w1 * scor1 + w2 * scor2) / (w1 + w2);
571 double scor_diff = std::abs(scor2 - scor1);
575 dmap[
"scor1"] = scor1;
576 dmap[
"scor2"] = scor2;
585 }
else if (erropt ==
"CHARGE") {
587 double x1 = dscordqrat1 * qrat1;
588 double x2 = dscordqrat2 * qrat2;
589 double dqq0 = dq0 / q0;
590 double dqq1 = dq1 / q1;
591 double dqq2 = dq2 / q2;
592 double rnum = (-
x1 *
x1 * dqq1 * dqq1 +
x2 *
x2 * dqq2 * dqq2 + (
x2 *
x2 -
x1 *
x1) * dqq0 * dqq0);
593 double rden = (
x1 *
x1 * dqq1 * dqq1 +
x2 *
x2 * dqq2 * dqq2 + (
x2 -
x1) * (
x2 -
x1) * dqq0 * dqq0);
594 double rfac = rnum / rden;
596 double dscor_diff = sqrt(rden);
597 double scor_diff = scor2 - scor1;
598 double scor_sig = std::abs(scor_diff) / dscor_diff;
600 double w1 = 0.5 * (1.0 +
rfac);
601 double w2 = 0.5 * (1.0 -
rfac);
602 scor = w1 * scor1 + w2 * scor2;
604 double ddscor1 = w1 *
x1 * dqq1;
605 double ddscor2 = w2 *
x2 * dqq2;
606 double ddscor0 = (w1 *
x1 + w2 *
x2) * dqq0;
607 double dscor = sqrt(ddscor1 * ddscor1 + ddscor2 * ddscor2 + ddscor0 * ddscor0);
608 dpos = pitch * dscor;
612 double dscor1 = std::abs(
x1) * sqrt(dqq1 * dqq1 + dqq0 * dqq0);
613 double dscor2 = std::abs(
x2) * sqrt(dqq2 * dqq2 + dqq0 * dqq0);
614 dmap[
"scor1"] = scor1;
615 dmap[
"dscor1"] = dscor1;
616 dmap[
"scor2"] = scor2;
617 dmap[
"dscor2"] = dscor2;
618 dmap[
"scordiff"] = scor_diff;
619 dmap[
"dscordiff"] = dscor_diff;
621 dmap[
"dscor"] = dscor;
625 ATH_MSG_VERBOSE(
" dq1, dq0, dq2: " << dq1 <<
" " << dq0 <<
" " << dq2);
647 savg += scor + strip0;
648 ATH_MSG_VERBOSE(
" QRAT corr " << splane(plane) <<
" nstrip=" << nstrip <<
" savg=" << savg <<
" qrat1=" << qrat1
649 <<
" qrat2=" << qrat2 <<
" scor1=" << scor1 <<
" scor2=" << scor2);
659 res.strip = istrip_peak;
660 res.position = pitch * (savg + 0.5 - 0.5 * maxstrip);
667 res.dposition = sqrt(dpos * dpos + dpostht * dpostht);
670 res.lstrip = nstrip - 1;
671 res.time = sfits[istrip_peak].time;
672 res.time_beforeT0Corr = sfits[istrip_peak].time_beforeT0Corr;
673 res.time_beforeBPCorr = sfits[istrip_peak].time_beforeBPCorr;
674 res.timeStatus = sfits[istrip_peak].timeStatus;
685 res.charge_beforeBPCorr =
686 sfits[istrip_peak].charge_beforeBPCorr + sfits[istrip_peak - 1].charge_beforeBPCorr + sfits[istrip_peak + 1].charge_beforeBPCorr;
690 ATH_MSG_VERBOSE(
" Position :: pos=" <<
res.position <<
" dpos:dtht=" << dpos <<
":" << dpostht <<
" ==>" <<
res.dposition
691 <<
" at tanth=" << tantheta);
710 int station =
m_idHelperSvc->cscIdHelper().stationName(idStrip0) - 49;
723 double newError = sqrt(dpos * dpos - old_dpostht * old_dpostht + new_dpostht * new_dpostht);
725 ATH_MSG_VERBOSE(
" Position :: pos=" <<
pos <<
" dpos:newdpos=" << dpos <<
" : " << newError <<
" " << old_dpostht <<
" "
728 if (slope < -990) { newError = sqrt(dpos * dpos + old_dpostht * old_dpostht); }
738 for (
unsigned int iresult = 0; iresult <
results.size(); ++iresult) {
741 new_results.push_back(
res);
747 int station =
m_idHelperSvc->cscIdHelper().stationName(idStrip0) - 49;
750 double pos =
res.position;
758 double dpos =
res.dposition;
760 res.dposition = sqrt(dpos * dpos + dpostht * dpostht);
763 new_results.push_back(
res);