41#include "CaloDetDescr/CaloDetDescrElement.h"
51#include "GaudiKernel/ISvcLocator.h"
54#include "Minuit2/MnMigrad.h"
55#include "Minuit2/MnUserParameterState.h"
56#include "Minuit2/FunctionMinimum.h"
59#include "CLHEP/Vector/ThreeVector.h"
60#include "CLHEP/Units/SystemOfUnits.h"
61#include "CLHEP/Units/PhysicalConstants.h"
70using CLHEP::Hep3Vector;
75#define BIN_RES_RXY 100.0
76#define BIN_RES_RZY 100.0
77#define BIN_RES_AXY (2.0*pi/128.0)
78#define BIN_RES_AZY (2.0*pi/128.0)
79#define MAX_NCELLS 500U
81#define MIN_ENERGY 1.0F
82#define MIN_ENERGY_MEV 1000.0F
161 ATH_MSG_INFO(
"Weighting cell position and time with energy density." );
164 ATH_MSG_INFO(
"Weighting cell position and time with energy." );
167 ATH_MSG_INFO(
"Not weighting cell position and time." );
176 <<
" from jobproperties not recognized. Setting to cosmics for TMF only." );
188 std::vector<TileDetDescriptor*>::const_iterator first =
m_tileMgr->tile_descriptors_begin();
189 std::vector<TileDetDescriptor*>::const_iterator last =
m_tileMgr->tile_descriptors_end();
190 for (; first != last; ++first) {
193 if (tileDD->
n_samp() != 3)
break;
195 hack = (tileDD->
dr(0) > 300);
197 for (
int is = 0; is < 3; is++)
200 }
else if (tileDD->
n_eta(0) == 10 && tileDD->
sign_eta() == -1) {
202 }
else if (tileDD->
n_eta(0) == 5 && tileDD->
sign_eta() == 1) {
205 for (
int is = 0; is < 3; is++)
208 }
else if (tileDD->
n_eta(0) == 5 && tileDD->
sign_eta() == -1) {
219 ATH_MSG_INFO(
"Old geometry detected: moving inner/outer radius by +10/-40 mm " );
226 ATH_MSG_INFO(
"Geometry read from TileDetDescr for track length calculation:" );
227 for (
int is = 0; is < 4; is++)
235 ATH_MSG_INFO(
"TileMuonFitter initialization completed" );
237 return StatusCode::SUCCESS;
247 return StatusCode::SUCCESS;
261 if (!cellContainer.
isValid()) {
290 return StatusCode::SUCCESS;
299 for (
unsigned int i = 0; i <
m_tileID->cell_hash_max(); i++) {
327 for (; collItr != lastColl; ++collItr) {
329 const CaloCell* cell = (*m_caloCells)[collItr];
332 if (tilecell == 0)
continue;
338 double ener = cell->energy();
339 double time = cell->time();
340 double deltatime = tilecell->
timeDiff();
343 if (fabs(caloDDE->
eta()) < 0.05 && caloDDE->
r() > 3500) {
345 <<
" Cell r: " << caloDDE->
r()
346 <<
" Tile diff: " << tilecell->
timeDiff() );
352 double volume = caloDDE->
volume();
386 double maxReg1Energy;
387 double maxReg2Energy;
392 maxReg1Energy = maxReg2Energy = 0.;
393 maxReg1Index = maxReg2Index = -1;
395 for (
int i = 0; i <
m_nCells; i++) {
398 }
else if (!
m_beamType.compare(
"collisions")) {
404 if (cellPosition > 0) {
418 if (maxReg1Index >= 0 && maxReg2Index >= 0) {
439 std::vector<double> X;
440 std::vector<double> Y;
441 std::vector<double> Z;
445 for (
int i = 0; i <
m_nCells; i++) {
450 double rr = sqrt(X[i] * X[i] + Y[i] * Y[i]);
469 double aa, bb, cc, dd;
470 double erraa, errbb, errcc, errdd;
471 aa = bb = cc = dd = erraa = errbb = errcc = errdd = 0.0;
482 MnUserParameters upar;
483 upar.Add(
"bb", bb, 0.1);
484 upar.Add(
"dd", dd, 0.1);
487 FunctionMinimum
min = migrad();
489 bool myIsValid =
min.IsValid();
494 bb =
min.UserState().Value(
"bb");
495 dd =
min.UserState().Value(
"dd");
498 errbb =
min.UserState().Error(
"bb");
499 errdd =
min.UserState().Error(
"dd");
510 msg(MSG::DEBUG) <<
"Minimum Value aa: " << aa
513 <<
" dd " << dd <<
endmsg;
514 msg(MSG::DEBUG) <<
"Minimum Error aa: " << erraa
517 <<
" dd " << errdd <<
endmsg;
551 for (
unsigned int n = 0; n <
m_linePar.size(); n++) {
558 << p0 <<
" " << p1 <<
" " << p2 <<
" " << p3 );
560 double correction = 0, weight = 1.0, weightsum = 0, time = 0;
565 Hep3Vector theZeroCrossingPosition(-1.0 * p0 / p1, 0.0, p2 - 1.0 * p3 * p0 / p1);
567 if (
msgLvl(MSG::DEBUG))
msg(MSG::DEBUG) <<
"Using cells to calculate time at Y=0: ";
569 for (
int i = 0; i <
m_nCells; i++) {
572 if (
msgLvl(MSG::DEBUG))
msg(MSG::DEBUG) << i <<
"/ ";
576 correction = (theZeroCrossingPosition - lineP).
mag() / c_light;
581 correction = 1.0 * correction;
583 correction = -1.0 * correction;
586 time += weight * (
m_cellTime[i] + correction);
614 for (
unsigned int n = 0; n <
m_linePar.size(); n++) {
621 << p0 <<
" " << p1 <<
" " << p2 <<
" " << p3 );
623 double correction = 0, weight = 1.0, weightsum = 0, time = 0;
628 Hep3Vector theZeroCrossingPosition(-1.0 * p2 / p3, p0 - 1.0 * p1 * p2 / p3, 0.0);
630 if (
msgLvl(MSG::DEBUG))
msg(MSG::DEBUG) <<
"Using cells to calculate time at Z=0: ";
632 for (
int i = 0; i <
m_nCells; i++) {
635 if (
msgLvl(MSG::DEBUG))
msg(MSG::DEBUG) << i <<
"/ ";
639 correction = (theZeroCrossingPosition - lineP).
mag() / c_light;
644 correction = 1.0 * correction;
646 correction = -1.0 * correction;
648 time += weight * (
m_cellTime[i] + correction);
692 StatusCode
sc = cosmicMuonContainer.
record(std::make_unique<TileCosmicMuonContainer>());
693 if (
sc.isFailure()) {
694 ATH_MSG_FATAL(
"Cannot record TileCosmicMuonContainer" << cosmicMuonContainer.
key() );
697 for (
unsigned int n = 0; n <
m_linePar.size(); n++) {
703 ATH_MSG_DEBUG(
"Starting BuildTileCosmicMuon at y=0 m_linePar: "
704 << p0 <<
" " << p1 <<
" " << p2 <<
" " << p3 );
708 if (!(fitok == 1) || p1 == 0.0) {
709 cosmicMuonContainer->push_back(theTileCosmicMuon);
711 Hep3Vector theDirection(1.0, p1, p3);
712 theDirection = theDirection.unit();
715 std::vector<double> ltop, lbot, etop, ebot;
716 std::vector<IdentifierHash> cells;
717 std::vector<double> segPath;
718 std::vector<int> segPartition, segModule, segSampling;
728 theTileCosmicMuon->
SetPositionZ(p2 - 1.0 * p3 * p0 / p1);
743 cosmicMuonContainer->push_back(theTileCosmicMuon);
765 StatusCode
sc = cosmicMuonContainer.
record(std::make_unique<TileCosmicMuonContainer>());
766 if (
sc.isFailure()) {
767 ATH_MSG_FATAL(
"Cannot record TileCosmicMuonContainer" << cosmicMuonContainer.
key() );
770 for (
unsigned int n = 0; n <
m_linePar.size(); n++) {
776 ATH_MSG_DEBUG(
"Starting BuildTileCosmicMuon at z=0 m_linePar: "
777 << p0 <<
" " << p1 <<
" " << p2 <<
" " << p3 );
781 if (!(fitok == 1) || p3 == 0.0) {
782 cosmicMuonContainer->push_back(theTileCosmicMuon);
784 Hep3Vector theDirection(1.0, p1, p3);
785 theDirection = theDirection.unit();
788 std::vector<double> ltop, lbot, etop, ebot;
789 std::vector<IdentifierHash> cells;
790 std::vector<double> segPath;
791 std::vector<int> segPartition, segModule, segSampling;
800 theTileCosmicMuon->
SetPositionY(p0 - 1.0 * p1 * p2 / p3);
816 cosmicMuonContainer->push_back(theTileCosmicMuon);
837 std::vector<Hep3Vector> intPoint;
838 std::vector<Hep3Vector> topIPO;
839 std::vector<Hep3Vector> bottomIPO;
840 std::vector<Hep3Vector> temp3v;
841 std::vector<Hep3Vector> plane;
842 Hep3Vector horizontalPlane;
848 for (is = 0; is < 3; is++) {
853 for (is = 0; is < 4; is++) {
857 if (aux_squared > 0) {
858 double x[2] = { (-1.0 * p0 * p1 + sqrt(aux_squared)) / (1 + p1 * p1), (-1.0 * p0 * p1
859 - sqrt(aux_squared)) / (1 + p1 * p1) };
860 for (uint8_t i = 0; i < 2; i++) {
861 temp3v[i].set(
x[i], p0 + p1 *
x[i], p2 + p3 *
x[i]);
862 if (
checkLBz(temp3v[i].
z())) intPoint.push_back(temp3v[i]);
868 if (aux_squared > 0) {
869 double x[2] = { (-1.0 * p0 * p1 + sqrt(aux_squared)) / (1 + p1 * p1), (-1.0 * p0 * p1
870 - sqrt(aux_squared)) / (1 + p1 * p1) };
871 for (uint8_t i = 0; i < 2; i++) {
872 temp3v[i].set(
x[i], p0 + p1 *
x[i], p2 + p3 *
x[i]);
873 if (
checkEBz(temp3v[i].
z())) intPoint.push_back(temp3v[i]);
878 uint8_t ncylint = intPoint.size();
881 for (ip = 0; ip < 6; ip++)
882 plane[ip].
set(0, 0, 0);
884 const double inv_p3 = 1. / p3;
885 for (ip = 0; ip < 2; ip++) {
895 for (is = 0; is < 3; is++) {
896 if (
checkLBr(plane[ip].
perp(), is)) intPoint.push_back(plane[ip]);
897 if (
checkEBr(plane[ip + 2].
perp(), is)) intPoint.push_back(plane[ip + 2]);
898 if (
checkEBr(plane[ip + 4].
perp(), is)) intPoint.push_back(plane[ip + 4]);
904 <<
" with planes: " << intPoint.size() - ncylint );
909 horizontalPlane.set(0, 0, 0);
910 uint16_t idx_hor = 99;
911 uint16_t i, j, k, jmax;
913 const double inv_p1 = 1. / p1;
915 horizontalPlane.set(-1.0 * p0 * inv_p1, 0, p2 - p3 * p0 * inv_p1);
917 for (i = 0; i < 3; i++)
918 if (
checkLBr(horizontalPlane.x(), i)) idx_hor = i;
921 for (i = 0; i < 3; i++)
922 if (
checkEBr(horizontalPlane.x(), i)) idx_hor = i;
927 <<
" X: " << horizontalPlane.x()
928 <<
" Z: " << horizontalPlane.z() );
932 uint16_t npoints = intPoint.size();
935 std::vector<uint8_t> neworder;
937 for (i = 0; i < npoints; i++) {
940 for (j = 0; j < npoints; j++) {
942 for (k = 0; k < neworder.size(); k++) {
943 if (j == neworder[k]) filled =
true;
945 if (filled)
continue;
946 if (intPoint[j].
y() >
ymax) {
947 ymax = intPoint[j].y();
951 if (jmax < 9999) neworder.push_back(jmax);
954 if (neworder.size() != npoints)
956 <<
" New order: " << neworder.size() );
962 if (idx_hor < 99) bottomIPO.push_back(horizontalPlane);
964 for (i = 0; i < npoints; i++) {
965 if (intPoint[neworder[i]].
y() > 0)
966 topIPO.push_back(intPoint[neworder[i]]);
968 bottomIPO.push_back(intPoint[neworder[i]]);
970 if (idx_hor < 99) topIPO.push_back(horizontalPlane);
973 <<
" and on bottom: " << bottomIPO.size() );
975 if (topIPO.size() > 1 && bottomIPO.size()) {
983 Hep3Vector temp_midpoint;
985 for (i = 0; i < topIPO.size() - 1; i++) {
987 <<
" X: " << topIPO[i].
x()
988 <<
" Y: " << topIPO[i].
y()
989 <<
" Z: " << topIPO[i].
z() );
991 temp_midpoint = (topIPO[i] + topIPO[i + 1]) / 2.;
995 temp_idx =
whichLBr(temp_midpoint.perp());
996 else if (
checkEBz(temp_midpoint.z()))
997 temp_idx =
whichEBr(temp_midpoint.perp());
1003 if (temp_idx < 0 || temp_idx > 2)
continue;
1004 ltop[temp_idx] += (topIPO[i] - topIPO[i + 1]).
mag();
1011 <<
" X: " << topIPO[topIPO.size() - 1].x()
1012 <<
" Y: " << topIPO[topIPO.size() - 1].y()
1013 <<
" Z: " << topIPO[topIPO.size() - 1].z() );
1016 for (i = 0; i < bottomIPO.size() - 1; i++) {
1018 <<
" X: " << bottomIPO[i].
x()
1019 <<
" Y: " << bottomIPO[i].
y()
1020 <<
" Z: " << bottomIPO[i].
z() );
1023 temp_midpoint = (bottomIPO[i] + bottomIPO[i + 1]) / 2.;
1027 temp_idx =
whichLBr(temp_midpoint.perp());
1028 else if (
checkEBz(temp_midpoint.z()))
1029 temp_idx =
whichEBr(temp_midpoint.perp());
1035 if (temp_idx < 0 || temp_idx > 2)
continue;
1036 lbot[temp_idx] += (bottomIPO[i] - bottomIPO[i + 1]).
mag();
1042 <<
" X: " << bottomIPO[bottomIPO.size() - 1].x()
1043 <<
" Y: " << bottomIPO[bottomIPO.size() - 1].y()
1044 <<
" Z: " << bottomIPO[bottomIPO.size() - 1].z() );
1054 std::vector<int> & segPartition, std::vector<int> & segModule, std::vector<int> & segSampling,
1064 std::vector<Hep3Vector> intPoint;
1065 std::vector<Hep3Vector> ordPoint;
1067 std::vector<Hep3Vector> temp3v;
1068 std::vector<Hep3Vector> plane;
1069 std::vector<Hep3Vector> modPlane;
1073 modPlane.resize(32);
1076 segPartition.clear();
1078 segSampling.clear();
1082 uint16_t i, j, k, jmax;
1083 for (is = 0; is < 4; is++) {
1087 if (aux_squared > 0) {
1088 double x[2] = { (-1.0 * p0 * p1 + sqrt(aux_squared)) / (1 + p1 * p1), (-1.0 * p0 * p1
1089 - sqrt(aux_squared)) / (1 + p1 * p1) };
1090 for (i = 0; i < 2; i++) {
1091 temp3v[i].set(
x[i], p0 + p1 *
x[i], p2 + p3 *
x[i]);
1092 if (
checkLBz(temp3v[i].
z())) intPoint.push_back(temp3v[i]);
1098 if (aux_squared > 0) {
1099 double x[2] = { (-1.0 * p0 * p1 + sqrt(aux_squared)) / (1 + p1 * p1), (-1.0 * p0 * p1
1100 - sqrt(aux_squared)) / (1 + p1 * p1) };
1101 for (i = 0; i < 2; i++) {
1102 temp3v[i].set(
x[i], p0 + p1 *
x[i], p2 + p3 *
x[i]);
1103 if (
checkEBz(temp3v[i].
z())) intPoint.push_back(temp3v[i]);
1108 uint16_t ncylint = intPoint.size();
1111 for (ip = 0; ip < 6; ip++)
1112 plane[ip].
set(0, 0, 0);
1114 for (ip = 0; ip < 2; ip++) {
1124 for (is = 0; is < 3; is++) {
1125 if (
checkLBr(plane[ip].
perp(), is)) intPoint.push_back(plane[ip]);
1126 if (
checkEBr(plane[ip + 2].
perp(), is)) intPoint.push_back(plane[ip + 2]);
1127 if (
checkEBr(plane[ip + 4].
perp(), is)) intPoint.push_back(plane[ip + 4]);
1131 uint16_t nvpint = intPoint.size() - ncylint;
1134 double tanTheta, tempX;
1135 for (ip = 0; ip < 32; ip++) {
1136 tanTheta = tan(
pi / 32. *
double(ip));
1137 if ((tanTheta - p1) != 0) {
1138 tempX = p0 / (tanTheta - p1);
1139 modPlane[ip].set(tempX, p0 + p1 * tempX, p2 + p3 * tempX);
1142 intPoint.push_back(modPlane[ip]);
1146 intPoint.push_back(modPlane[ip]);
1150 uint16_t nmpint = intPoint.size() - ncylint - nvpint;
1151 uint16_t npoints = intPoint.size();
1154 <<
" cylinders: " << ncylint
1155 <<
" vertical planes: " << nvpint
1156 <<
" module planes: " << nmpint );
1161 std::vector<int> neworder;
1163 for (i = 0; i < npoints; i++) {
1166 for (j = 0; j < npoints; j++) {
1168 for (k = 0; k < neworder.size(); k++) {
1169 if (j == neworder[k]) filled =
true;
1171 if (filled)
continue;
1172 if (intPoint[j].
y() >
ymax) {
1173 ymax = intPoint[j].y();
1177 if (jmax < 9999) neworder.push_back(jmax);
1180 if (neworder.size() != npoints)
1181 ATH_MSG_DEBUG(
" Npoints " << npoints <<
" New order: " << neworder.size() );
1183 for (i = 0; i < npoints; i++)
1184 ordPoint.push_back(intPoint[neworder[i]]);
1194 if (ordPoint.size() > 1) {
1195 Hep3Vector temp_midpoint;
1196 int temp_idr, temp_idp, temp_idm;
1197 bool extra_debug =
false;
1198 for (i = 0; i < ordPoint.size(); i++) {
1200 <<
" X: " << ordPoint[i].
x()
1201 <<
" Y: " << ordPoint[i].
y()
1202 <<
" Z: " << ordPoint[i].
z() );
1204 if (i == ordPoint.size() - 1)
break;
1206 temp_midpoint = (ordPoint[i] + ordPoint[i + 1]) / 2.;
1209 temp_idr =
whichLBr(temp_midpoint.perp());
1210 temp_idp = (temp_midpoint.z() > 0) ? 1 : 2;
1211 }
else if (
checkEBz(temp_midpoint.z())) {
1212 temp_idr =
whichEBr(temp_midpoint.perp());
1213 temp_idp = (temp_midpoint.z() > 0) ? 3 : 4;
1218 if (temp_idr < 0 || temp_idr > 2)
continue;
1219 if (temp_idm < 0 || temp_idm > 63)
continue;
1221 segPath.push_back((ordPoint[i] - ordPoint[i + 1]).
mag());
1222 segPartition.push_back(temp_idp);
1223 segModule.push_back(temp_idm);
1224 segSampling.push_back(temp_idr);
1230 for (i = 0; i < segPath.size(); i++) {
1231 if (segPath[i] > 1100) extra_debug =
true;
1233 <<
" Path : " << segPath[i]
1234 <<
" Partition : " << segPartition[i]
1235 <<
" Module : " << segModule[i]
1236 <<
" Sampling : " << segSampling[i] );
1240 if (
msgLvl(MSG::DEBUG) && extra_debug) {
1241 msg(MSG::DEBUG) <<
"Large segment p0: " << p0
1244 <<
" p3 " << p3 <<
endmsg;
1246 msg(MSG::DEBUG) <<
"Intersections: " << npoints
1247 <<
" cylinders: " << ncylint
1248 <<
" vertical planes: " << nvpint
1249 <<
" module planes: " << nmpint <<
endmsg;
1251 for (i = 0; i < ordPoint.size(); i++) {
1252 msg(MSG::DEBUG) <<
"Ordered points : " << i
1253 <<
" X: " << ordPoint[i].x()
1254 <<
" Y: " << ordPoint[i].y()
1255 <<
" Z: " << ordPoint[i].z() <<
endmsg;
1258 for (i = 0; i < segPath.size(); i++) {
1259 msg(MSG::DEBUG) <<
"Segment " << i
1260 <<
" Path : " << segPath[i]
1261 <<
" Partition : " << segPartition[i]
1262 <<
" Module : " << segModule[i]
1263 <<
" Sampling : " << segSampling[i] <<
endmsg;
1308 if (x1 < 0) x1 = -1.0 * x1;
1318 if (x1 < 0.0) x1 = -1.0 * x1;
1328 if (s1 > 3U)
return false;
1329 if (x1 < 0.0) x1 = -1.0 * x1;
1339 if (s1 > 3U)
return false;
1340 if (x1 < 0.0) x1 = -1.0 * x1;
1351 for (
int i = 0; i < 3; i++) {
1361 for (
int i = 0; i < 3; i++) {
1370 double phi = tempvec.phi();
1376 mod = int(
phi * (64.0 / (2.0 *
pi)));
1383 , std::vector<IdentifierHash> & cells,
int index) {
1386 double distance_cut[2][3] = { { 300., 375., 860. }, { 750., 750., 1700. } };
1389 for (is = 0; is < 3; is++) {
1399 for (; collItr != lastColl; ++collItr) {
1401 const CaloCell* cell = (*m_caloCells)[collItr];
1403 if (tilecell == 0)
continue;
1409 double volume = caloDDE->
volume();
1410 if (volume == 0.0) {
1411 ATH_MSG_DEBUG(
"Warning: Skipping cell with zero volume!" );
1415 int sample =
m_tileID->sample(cell_id);
1418 dataP.set(caloDDE->
x(), caloDDE->
y(), caloDDE->
z());
1420 double distance = (dataP - lineP).
mag();
1421 if (distance < distance_cut[
section - 1][sample]) {
1422 cells.push_back(cell_idhash);
1423 if (caloDDE->
y() > 0.0) etop[sample] += cell->energy();
1424 else ebot[sample] += cell->energy();
1458 double p0, p1, p2, p3;
1476 << p0 <<
" " << p1 <<
" " << p2 <<
" " << p3 );
1480 if (!(fitok == 1) || p1 == 0.0) {
1481 sc = theComTime.
record(std::make_unique<ComTime>());
1483 Hep3Vector theZeroCrossingPosition(-1.0 * p0 / p1, 0.0, p2 - 1.0 * p3 * p0 / p1);
1484 Hep3Vector theDirection(1.0, p1, p3);
1485 theDirection = theDirection.unit();
1488 sc = theComTime.
record(std::make_unique<ComTime>(0.0, ztime, theZeroCrossingPosition, theDirection));
1490 if (
msgLvl(MSG::DEBUG)) {
1492 msg(MSG::DEBUG) <<
"Time: " << ztime
1493 <<
" Position X: " << theZeroCrossingPosition.getX()
1494 <<
" Position Y: " << theZeroCrossingPosition.getY()
1495 <<
" Position Z: " << theZeroCrossingPosition.getZ() <<
endmsg;
1497 msg(MSG::DEBUG) <<
"Direction u: " << theDirection.getX()
1498 <<
" Direction v: " << theDirection.getY()
1499 <<
" Direction w: " << theDirection.getZ() <<
endmsg;
1503 if (
sc.isFailure()) {
1522 double p0, p1, p2, p3;
1540 << p0 <<
" " << p1 <<
" " << p2 <<
" " << p3 );
1544 if (!(fitok == 1) || p3 == 0.0) {
1545 sc = theComTime.
record(std::make_unique<ComTime>());
1547 Hep3Vector theZeroCrossingPosition(-1.0 * p2 / p3, p0 - 1.0 * p1 * p2 / p3, 0.0);
1548 Hep3Vector theDirection(1.0, p1, p3);
1549 theDirection = theDirection.unit();
1552 sc = theComTime.
record(std::make_unique<ComTime>(0.0, ztime, theZeroCrossingPosition, theDirection));
1554 if (
msgLvl(MSG::DEBUG)) {
1556 msg(MSG::DEBUG) <<
"Time: " << ztime
1557 <<
" Position X: " << theZeroCrossingPosition.getX()
1558 <<
" Position Y: " << theZeroCrossingPosition.getY()
1559 <<
" Position Z: " << theZeroCrossingPosition.getZ() <<
endmsg;
1561 msg(MSG::DEBUG) <<
"Direction u: " << theDirection.getX()
1562 <<
" Direction v: " << theDirection.getY()
1563 <<
" Direction w: " << theDirection.getZ() <<
endmsg;
1567 if (
sc.isFailure()) {
1581 if (x1 == x2) x1 += 0.001F;
1582 if (y1 == y2) y1 += 0.001F;
1584 double a = (y1 - y2) / (x1 - x2);
1585 double b = y1 -
a * x1;
1587 raio = fabs(b) / sqrt(
a *
a + 1.0);
1590 angu = atan(
a) +
pi / 2.0;
1591 else if (
a > 0.0 && b < 0.0)
1592 angu = atan(
a) -
pi / 2.0;
1593 else if (
a < 0.0 && b < 0.0)
1594 angu = atan(
a) -
pi / 2.0;
1596 angu = atan(
a) +
pi / 2.0;
1599 if (angu < 0.0) angu = 2.0 *
pi + angu;
1607 x1 = (
r - sin(
a +
pi)) / cos(
a +
pi) - offset;
1610 x2 = (
r + sin(
a +
pi)) / cos(
a +
pi) - offset;
1613 aa = (y2 - y1) / (x2 - x1);
1618 float v0, v1, v2, d0, d1, d2;
1624 d0 = v1 * w[2] - w[1] * v2;
1625 d1 = w[0] * v2 - v0 * w[2];
1626 d2 = v0 * w[1] - w[0] * v1;
1628 return sqrt(d0 * d0 + d1 * d1 + d2 * d2);
1632 w[0] = ci1.
x - ci2.
x;
1633 w[1] = ci1.
y - ci2.
y;
1634 w[2] = ci1.
z - ci2.
z;
1636 float invmod = 1.0F / sqrt(w[0] * w[0] + w[1] * w[1] + w[2] * w[2]);
1656 unsigned int cnt = 0U;
1658 for (
unsigned int i = 0U; i < size; i++) {
1659 if (!
m_cellInfo[i].use || i == index1 || i == index2)
continue;
1667 if (cnt > 0U) skew /= (int) cnt;
1677 double skew, skew_min = 999999999.9;
1678 unsigned int cnt, cnt_max = 0U;
1680 for (i = 1; i < NPoints; i++) {
1681 for (j = 0; j < i; j++) {
1684 if (cnt > cnt_max || (cnt == cnt_max && skew < skew_min)) {
1699 const float distance_cut[2][3] = { { 300.0, 820.0, 470.0 }, { 350.0, 540.0, 740.0 } };
1704 for (
int i = 0; i <
m_nCells; i++) {
1716 cell.track_index = -1;
1723 cell.dist = distance_cut[
section - 1][sample];
1737 for (
unsigned int i = 0; i < NPoints; i++) {
1782 for (i = 1; i < NPoints; i++) {
1783 for (j = 0; j < i; j++) {
1787 if (rxy < nminrxy || rxy > nmaxrxy || axy < nminaxy || axy > nmaxaxy || rzy < nminrzy
1788 || rzy > nmaxrzy || azy < nminazy || azy > nmaxazy)
continue;
1792 arxy += rxy * weight;
1793 aaxy += axy * weight;
1794 arzy += rzy * weight;
1795 aazy += azy * weight;
1800 const double inv_aw = 1. / aw;
1801 rxy = arxy * inv_aw;
1802 axy = aaxy * inv_aw;
1803 rzy = arzy * inv_aw;
1804 azy = aazy * inv_aw;
1812 bool compute =
true;
1823 unsigned int index1, index2;
1837 double rxy, axy, rzy, azy;
1847 double aa, bb, cc, dd;
1852 addTrack(aa, bb, (aa - cc) / dd, bb / dd);
1856 <<
" cc: " << (aa - cc) / dd
1857 <<
" dd " << bb / dd );
1864 std::vector<double> X;
1865 std::vector<double> Y;
1866 std::vector<double> Z;
1872 for (
int i = 0; i <
m_nCells; i++) {
1886 std::vector<double> par;
const boost::regex rr(r_r)
Scalar perp() const
perp method - perpendicular length
Scalar phi() const
phi method
Scalar mag() const
mag method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
#define CHECK(...)
Evaluate an expression and check for errors.
Handle class for reading from StoreGate.
Handle class for recording to StoreGate.
AthAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor with parameters:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
const ServiceHandle< StoreGateSvc > & detStore() const
bool msgLvl(const MSG::Level lvl) const
CaloCell_Base_ID::SUBCALO SUBCALO
Data object for each calorimeter readout cell.
This class groups all DetDescr information related to a CaloCell.
float eta() const
cell eta
float volume() const
cell volume
This is a "hash" representation of an Identifier.
Auxiliary to TileMuonFitter.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
virtual const std::string & key() const override final
Return the StoreGate ID for the referenced object.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
float timeDiff(void) const
get time diff for two PMTs (data member)
Class containing detailed results from TileMuonFitter.
void SetSegmentModule(const std::vector< int > &module)
void SetPathBottom(const std::vector< double > &path)
void SetEnergyBottom(const std::vector< double > &energy)
void SetPositionZ(double posz)
void SetPositionY(double posy)
void SetTime(double time)
Setters.
void SetDirectionTheta(double theta)
void SetSegmentPath(const std::vector< double > &path)
void SetSegmentSampling(const std::vector< int > &sampling)
void SetSegmentPartition(const std::vector< int > &partition)
void SetEnergyTop(const std::vector< double > &energy)
void SetFitNCells(int ncells)
void SetTrackCellHash(const std::vector< IdentifierHash > &cells)
void SetPositionX(double posx)
void SetPathTop(const std::vector< double > &path)
void SetFitQuality(double quality)
void SetDirectionPhi(double phi)
float zcenter(unsigned int samp) const
float rcenter(unsigned int samp) const
int n_eta(unsigned int samp) const
float dz(unsigned int samp) const
float dr(unsigned int samp) const
bool m_doHoughTransform
Flag to use Hough Transform instead of Fit.
bool isHaloMuon(double azy)
void addTrack(double aa, double bb, double cc, double dd)
void doHough(double &rxy, double &axy, double &rzy, double &azy)
int whichEBr(double x1)
Returns sampling index if x1 is within EB r coordinate bounds.
unsigned int CntCells(unsigned int index1, unsigned int index2, double &skew)
std::vector< double > m_tileDD_zEBC
Z bounds of EBC, loaded from Detector Description.
TileMuonFitter(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
void trackSegmentIntersection(std::vector< double > &segPath, std::vector< int > &segPartition, std::vector< int > &segModule, std::vector< int > &segSampling, int index)
Calculates length of track intersection with TileCal (by sampling and module).
std::vector< double > m_tileDD_zLB
Z bounds of LB, loaded from Detector Description.
int m_minimumCells
Minimum number of cells needed for fit.
SG::ReadHandleKey< CaloCellContainer > m_cellContainerKey
std::vector< IdentifierHash > m_cellHash
Selected cell's identifier hash.
void hough2cart(double r, double a, double offset, double &aa, double &bb)
void buildComTimeAtYequal0(int fitok)
Creates output ComTime object in StoreGate.
void buildTileCosmicMuonAtYequal0(int fitok)
Creates output TileCosmicMuon object in StoreGate.
void buildCells()
Creates an internal cell container (just vectors) from the input CaloCellContainer.
const CaloCellContainer * m_caloCells
bool guessTrack(unsigned int &index1, unsigned int &index2)
void buildComTime(int fitok)
Selects between the two next methods.
double m_deltaTimeCut
Cell Delta Time cut.
bool m_doDensity
Flag defining the energy weighting parameter: energy density or plain energy.
int m_nCells
Number of cells selected for fit.
void buildTileCosmicMuonAtZequal0(int fitok)
Creates output TileCosmicMuon object in StoreGate.
bool checkLBr(double x1, uint8_t s1)
Checks if x1 is within LB r coordinate bounds for sampling s1.
unsigned int buildCellInfoVector()
std::vector< CellInfo > m_cellInfo
int whichModule(CLHEP::Hep3Vector tempvec)
Returns module index for TVector3 input.
void points2dir(CellInfo &ci1, CellInfo &ci2, float *w)
std::vector< double > m_cellEnergy
Selected cell's energy.
int fitTrack()
Fits a straight track to the cell centers, using the auxiliary class TileMuonTrackDistance.
void calculateTime()
Calculates time in reference plane.
std::vector< CLHEP::Hep3Vector > m_cellPosition
Position of selected cell's center.
virtual StatusCode initialize() override
void buildComTimeAtZequal0(int fitok)
Creates output ComTime object in StoreGate.
bool m_doWeighted
Flag to weigh or not the chi-square with an energy parameter.
std::vector< std::vector< double > > m_linePar
Vector with the fitted four track parameters.
void calculateTimeAtZequal0()
Extrapolates cell time to z=0.
const TileDetDescrManager * m_tileMgr
std::vector< double > m_cellWeight
Selected cell's weight for fit.
bool checkEBz(double x1)
Checks if x1 is within EB z coordinate bounds.
void trackIntersection(std::vector< double > <op, std::vector< double > &lbot, int index)
Calculates length of track intersection with TileCal (by sampling).
SG::WriteHandleKey< TileCosmicMuonContainer > m_cosmicMuonContainerKey
std::string m_beamType
Flag to indicate: cosmics, singlebeam or collisions.
float dist2line(CellInfo &ci, float *pos, float *w)
virtual ~TileMuonFitter()
virtual StatusCode finalize() override
bool checkEBCz(double x1)
Checks if x1 is within EBC z coordinate bounds.
std::vector< double > m_fitMinimum
Chi-square minumum.
void cart2hough(float x1, float y1, float x2, float y2, double &raio, double &angu)
std::vector< double > m_tileDD_zEBA
Z bounds of EBA, loaded from Detector Description.
bool checkEBAz(double x1)
Checks if x1 is within EBA z coordinate bounds.
void buildTileCosmicMuon(int fitok)
Selects between the two next methods.
void calculateTimeAtYequal0()
Extrapolates cell time to y=0.
std::vector< double > m_zeroCrossingTime
Time at y=0.
int whichLBr(double x1)
Returns sampling index if x1 is within LB r coordinate bounds.
double m_eThreshold
Cell energy threshold.
int houghTrack()
Fits a straight track to the cells centers, using a Hough Transform algorithm.
const TileHWID * m_tileHWID
virtual StatusCode execute() override
float selectCells(float *p, float *w)
std::vector< double > m_cellTime
Selected cell's time.
bool checkLBz(double x1)
Checks if x1 is within LB z coordinate bounds.
std::vector< double > m_tileDD_radiusEB
Radial bounds of the 3 samplings in EB, loaded from Detector Description.
std::vector< double > m_cellDeltaTime
Selected cell's time difference between two PMTs.
static const CaloCell_ID::SUBCALO m_caloIndex
std::vector< double > m_tileDD_radiusLB
Radial bounds of the 3 samplings in LB, loaded from Detector Description.
bool checkEBr(double x1, uint8_t s1)
Checks if x1 is within EB r coordinate bounds for sampling s1.
void energyInTrack(std::vector< double > &etop, std::vector< double > &ebot, std::vector< IdentifierHash > &cells, int index)
Sums up energy in TileCal cells close to the track (by sampling).
ROOT::Minuit2::TileMuonTrackDistance * m_theTrack
Auxiliary class representing the function to be minimized - weighted sum of squares of orthogonal dis...
SG::WriteHandleKey< ComTime > m_comTimeKey
bool eventSelection()
Checks if there are good cells on the top and bottom modules.
void setEventDefaults()
Reset variables.
const std::string selection