Skip to content

Commit 276475b

Browse files
peressounkoDmitri Peresunko
andauthored
add nonlinearity options; improve track matching (#5558)
Co-authored-by: Dmitri Peresunko <Dmitri.Peresunko@cern.ch>
1 parent 658cbda commit 276475b

File tree

1 file changed

+139
-22
lines changed

1 file changed

+139
-22
lines changed

Common/TableProducer/caloClusterProducer.cxx

Lines changed: 139 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,15 @@
1515
#include "Framework/AnalysisDataModel.h"
1616
#include "Common/DataModel/TrackSelectionTables.h"
1717
#include "Common/DataModel/CaloClusters.h"
18+
#include "Common/Core/trackUtilities.h"
19+
#include "ReconstructionDataFormats/TrackParametrization.h"
20+
#include "DetectorsBase/Propagator.h"
1821

1922
#include "CommonUtils/NameConf.h"
2023
#include "CCDB/BasicCCDBManager.h"
2124
#include "SimulationDataFormat/MCTruthContainer.h"
2225

26+
#include "DataFormatsParameters/GRPMagField.h"
2327
#include "DataFormatsPHOS/Cell.h"
2428
#include "DataFormatsPHOS/Cluster.h"
2529
#include "DataFormatsPHOS/TriggerRecord.h"
@@ -44,6 +48,7 @@ struct caloClusterProducerTask {
4448
Configurable<bool> isMC{"isMC", 0, "0 - data, 1 - MC"};
4549
Configurable<bool> useCoreE{"coreE", 0, "0 - full energy, 1 - core energy"};
4650
Configurable<bool> skipL1phase{"skipL1phase", false, "skip or apply L1phase time correction"};
51+
Configurable<int> mNonlinType{"nonlinType", 1, "0:no corr, 1: default"};
4752
Configurable<std::vector<double>> cpvMinE{"cpvCluMinAmp", {20., 50., 50.}, "minimal CPV cluster amplitude per module"};
4853
Configurable<std::string> mBadMapPath{"badmapPath", "PHS/Calib/BadMap", "path to BadMap snapshot"};
4954
Configurable<std::string> mCalibPath{"calibPath", "PHS/Calib/CalibParams", "path to Calibration snapshot"};
@@ -61,6 +66,8 @@ struct caloClusterProducerTask {
6166
std::vector<int> mclabels;
6267
std::vector<float> mcamplitudes;
6368

69+
int mRunNumber{0};
70+
6471
static constexpr int16_t kCpvX = 7; // grid 6 steps along z and 7 along phi as largest match ellips 20x20 cm
6572
static constexpr int16_t kCpvZ = 6;
6673
static constexpr int16_t kCpvCells = 4 * kCpvX * kCpvZ; // 4 modules
@@ -740,6 +747,17 @@ struct caloClusterProducerTask {
740747
} else {
741748
return;
742749
}
750+
751+
if (mRunNumber != bcs.begin().runNumber()) {
752+
mRunNumber = bcs.begin().runNumber();
753+
LOG(info) << ">>>>>>>>>>>> Current run number: " << mRunNumber;
754+
o2::parameters::GRPMagField* grpo = ccdb->getForTimeStamp<o2::parameters::GRPMagField>("GLO/Config/GRPMagField", timestamp);
755+
if (grpo == nullptr) {
756+
LOGF(fatal, "Run 3 GRP object (type o2::parameters::GRPMagField) is not available in CCDB for run=%d at timestamp=%llu", mRunNumber, timestamp);
757+
}
758+
o2::base::Propagator::initFieldFromGRP(grpo);
759+
}
760+
743761
std::map<int64_t, int> bcMap;
744762
int bcId = 0;
745763
for (auto bc : bcs) {
@@ -934,7 +952,8 @@ struct caloClusterProducerTask {
934952
// calculate coordinate in PHOS plane
935953
int16_t module;
936954
float trackX, trackZ;
937-
if (impactOnPHOS(track.trackEtaEmcal(), track.trackPhiEmcal(), module, trackX, trackZ)) {
955+
auto trackPar = getTrackPar(track);
956+
if (impactOnPHOS(trackPar, track.trackEtaEmcal(), track.trackPhiEmcal(), track.collision().posZ(), module, trackX, trackZ)) {
938957
int index = CpvMatchIndex(module, trackX, trackZ);
939958
trackMatchPoints[index].emplace_back(trackX, trackZ, track.globalIndex());
940959
}
@@ -1137,6 +1156,17 @@ struct caloClusterProducerTask {
11371156
} else {
11381157
return;
11391158
}
1159+
1160+
if (mRunNumber != bcs.begin().runNumber()) {
1161+
mRunNumber = bcs.begin().runNumber();
1162+
LOG(info) << ">>>>>>>>>>>> Current run number: " << mRunNumber;
1163+
o2::parameters::GRPMagField* grpo = ccdb->getForTimeStamp<o2::parameters::GRPMagField>("GLO/Config/GRPMagField", timestamp);
1164+
if (grpo == nullptr) {
1165+
LOGF(fatal, "Run 3 GRP object (type o2::parameters::GRPMagField) is not available in CCDB for run=%d at timestamp=%llu", mRunNumber, timestamp);
1166+
}
1167+
o2::base::Propagator::initFieldFromGRP(grpo);
1168+
}
1169+
11401170
std::map<int64_t, int> bcMap;
11411171
int bcId = 0;
11421172
for (auto bc : bcs) {
@@ -1353,7 +1383,8 @@ struct caloClusterProducerTask {
13531383
// calculate coordinate in PHOS plane
13541384
int16_t module;
13551385
float trackX, trackZ;
1356-
if (impactOnPHOS(track.trackEtaEmcal(), track.trackPhiEmcal(), module, trackX, trackZ)) {
1386+
auto trackPar = getTrackPar(track);
1387+
if (impactOnPHOS(trackPar, track.trackEtaEmcal(), track.trackPhiEmcal(), track.collision().posZ(), module, trackX, trackZ)) {
13571388
int index = CpvMatchIndex(module, trackX, trackZ);
13581389
trackMatchPoints[index].emplace_back(trackX, trackZ, track.globalIndex());
13591390
}
@@ -1570,14 +1601,18 @@ struct caloClusterProducerTask {
15701601
return (module - 1) * kCpvX * kCpvZ + ix * kCpvZ + iz; // modules: 1,2,3,4
15711602
}
15721603

1573-
bool impactOnPHOS(float trackEta, float trackPhi, int16_t& module, float& trackX, float& trackZ)
1604+
bool impactOnPHOS(o2::track::TrackParametrization<float>& trackPar, float trackEta, float trackPhi, float zvtx, int16_t& module, float& trackX, float& trackZ)
15741605
{
1606+
// eta,phi was calculated at EMCAL radius.
1607+
// Extrapolate to PHOS assuming zeroB and current vertex
15751608
// Check if direction in PHOS acceptance+20cm and return phos module number and coordinates in PHOS module plane
1576-
const float phiMin = 240. * 0.017453293; // degToRad
1609+
const float phiMin = 240. * 0.017453293; // PHOS phi coverage-10degree *degToRad
15771610
const float phiMax = 323. * 0.017453293; // PHOS+20 cm * degToRad
1611+
const float xmax = 85.; // Maximal x distance per module
15781612
const float etaMax = 0.178266;
1579-
const float r = 460.; // track propagated to this radius
1580-
if (trackPhi < phiMin || trackPhi > phiMax || abs(trackEta) > etaMax) {
1613+
double bz = o2::base::Propagator::Instance()->getNominalBz(); // magnetic field
1614+
1615+
if (trackPhi < phiMin || trackPhi > phiMax || abs(trackEta) > etaMax) { // do not match even approximately
15811616
return false;
15821617
}
15831618

@@ -1596,30 +1631,112 @@ struct caloClusterProducerTask {
15961631
module = 4;
15971632
}
15981633

1599-
double posG[3] = {r * cos(trackPhi), r * sin(trackPhi), r * sinh(trackEta)};
1600-
double posL[3];
1634+
// get PHOS radius
1635+
constexpr float shiftY = -1.26; // Depth-optimized
1636+
double posL[3] = {0., 0., shiftY}; // local position at the center of module
1637+
double posG[3] = {0};
1638+
geomPHOS->getAlignmentMatrix(module)->LocalToMaster(posL, posG);
1639+
double rPHOS = sqrt(posG[0] * posG[0] + posG[1] * posG[1]);
1640+
double alpha = (230. + 20. * module) * 0.017453293;
1641+
1642+
// During main reconstruction track was propagated to radius 460 cm with accounting material
1643+
// now material is not available. Therefore, start from main rec. position and extrapoate to actual radius without material
1644+
// Get track parameters at point where main reconstruction stop
1645+
float xPHOS = 460.f, xtrg = 0.f;
1646+
if (!trackPar.getXatLabR(xPHOS, xtrg, bz, o2::track::DirType::DirOutward)) {
1647+
return false;
1648+
}
1649+
auto prop = o2::base::Propagator::Instance();
1650+
if (!trackPar.rotate(alpha) ||
1651+
!prop->PropagateToXBxByBz(trackPar, xtrg, 0.95, 10, o2::base::Propagator::MatCorrType::USEMatCorrNONE)) {
1652+
return false;
1653+
}
1654+
// calculate xyz from old (Phi, eta) and new r
1655+
float r = std::sqrt(trackPar.getX() * trackPar.getX() + trackPar.getY() * trackPar.getY());
1656+
trackPar.setX(r * std::cos(trackPhi - alpha));
1657+
trackPar.setY(r * std::sin(trackPhi - alpha));
1658+
trackPar.setZ(r / std::tan(2. * std::atan(std::exp(-trackEta))));
1659+
1660+
if (!prop->PropagateToXBxByBz(trackPar, rPHOS, 0.95, 10, o2::base::Propagator::MatCorrType::USEMatCorrNONE)) {
1661+
return false;
1662+
}
1663+
alpha = trackPar.getAlpha();
1664+
double ca = cos(alpha), sa = sin(alpha);
1665+
posG[0] = trackPar.getX() * ca - trackPar.getY() * sa;
1666+
posG[1] = trackPar.getY() * ca + trackPar.getX() * sa;
1667+
posG[2] = trackPar.getZ();
1668+
1669+
geomPHOS->getAlignmentMatrix(module)->MasterToLocal(posG, posL);
1670+
trackX = posL[0];
1671+
trackZ = posL[1];
1672+
// If trackX beyond the module, switch to the next one
1673+
if (abs(trackX) < xmax || (trackX < -xmax && module == 1) || (trackX > xmax && module == 4)) {
1674+
return true;
1675+
}
1676+
// re-do extrapolation to correct module
1677+
if (trackX < xmax && module > 1) {
1678+
--module;
1679+
} else {
1680+
if (trackX > xmax && module < 4) {
1681+
++module;
1682+
}
1683+
}
1684+
// repeat extrapolation for correct module
1685+
alpha = (230. + 20. * module) * 0.017453293;
1686+
posL[0] = 0.;
1687+
posL[1] = 0.;
1688+
posL[2] = shiftY; // local position at the center of module
1689+
geomPHOS->getAlignmentMatrix(module)->LocalToMaster(posL, posG);
1690+
rPHOS = sqrt(posG[0] * posG[0] + posG[1] * posG[1]);
1691+
1692+
if (!trackPar.rotate(alpha) ||
1693+
!prop->PropagateToXBxByBz(trackPar, xtrg, 0.95, 10, o2::base::Propagator::MatCorrType::USEMatCorrNONE)) {
1694+
return false;
1695+
}
1696+
// calculate xyz from old (Phi, eta) and new r
1697+
r = std::sqrt(trackPar.getX() * trackPar.getX() + trackPar.getY() * trackPar.getY());
1698+
trackPar.setX(r * std::cos(trackPhi - alpha));
1699+
trackPar.setY(r * std::sin(trackPhi - alpha));
1700+
trackPar.setZ(r / std::tan(2. * std::atan(std::exp(-trackEta))));
1701+
1702+
if (!prop->PropagateToXBxByBz(trackPar, rPHOS, 0.95, 10, o2::base::Propagator::MatCorrType::USEMatCorrNONE)) {
1703+
return false;
1704+
}
1705+
alpha = trackPar.getAlpha();
1706+
ca = cos(alpha);
1707+
sa = sin(alpha);
1708+
posG[0] = trackPar.getX() * ca - trackPar.getY() * sa;
1709+
posG[1] = trackPar.getY() * ca + trackPar.getX() * sa;
1710+
posG[2] = trackPar.getZ();
1711+
16011712
geomPHOS->getAlignmentMatrix(module)->MasterToLocal(posG, posL);
16021713
trackX = posL[0];
1603-
trackZ = posL[2];
1714+
trackZ = posL[1];
16041715
return true;
16051716
}
16061717

16071718
float Nonlinearity(float en)
16081719
{
16091720
// Correct for non-linearity
1610-
// Parameters to be read from ccdb
1611-
const double a = 9.34913e-01;
1612-
const double b = 2.33e-03;
1613-
const double c = -8.10e-05;
1614-
const double d = 3.2e-02;
1615-
const double f = -8.0e-03;
1616-
const double g = 1.e-01;
1617-
const double h = 2.e-01;
1618-
const double k = -1.48e-04;
1619-
const double l = 0.194;
1620-
const double m = 0.0025;
1621-
1622-
return en * (a + b * en + c * en * en + d / en + f / ((en - g) * (en - g) + h) + k / ((en - l) * (en - l) + m));
1721+
switch (mNonlinType) {
1722+
case 0:
1723+
return en;
1724+
case 1: {
1725+
const double a = 9.34913e-01;
1726+
const double b = 2.33e-03;
1727+
const double c = -8.10e-05;
1728+
const double d = 3.2e-02;
1729+
const double f = -8.0e-03;
1730+
const double g = 1.e-01;
1731+
const double h = 2.e-01;
1732+
const double k = -1.48e-04;
1733+
const double l = 0.194;
1734+
const double m = 0.0025;
1735+
return en * (a + b * en + c * en * en + d / en + f / ((en - g) * (en - g) + h) + k / ((en - l) * (en - l) + m));
1736+
}
1737+
default:
1738+
return en;
1739+
}
16231740
}
16241741
};
16251742

0 commit comments

Comments
 (0)