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