Skip to content

Commit 0a1fe0e

Browse files
matthias-kleinerwiechula
authored andcommitted
TPC: Optimising scaling of distortions in MC
- Making simulation of scaled distortions in the digitizer fully consistent with the scaled corrections in the reconstruction - cleaning some old code
1 parent 8572af8 commit 0a1fe0e

File tree

3 files changed

+193
-16
lines changed

3 files changed

+193
-16
lines changed

Detectors/TPC/simulation/src/Digitizer.cxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ void Digitizer::recalculateDistortions()
257257
mSpaceChargeDer->calcGlobalCorrWithGlobalDistIterative(side, nullptr, 0);
258258

259259
LOGP(info, "Calculating scaled distortions with scaling factor {}", mLumiScaleFactor);
260-
mSpaceCharge->calcGlobalDistWithGlobalCorrIterative(side, mSpaceChargeDer.get(), mLumiScaleFactor);
260+
mSpaceCharge->calcGlobalDistWithGlobalCorrIterativeLinearCartesian(side, mSpaceChargeDer.get(), mLumiScaleFactor);
261261
}
262262
// set new lumi of avg map
263263
mSpaceCharge->setMeanLumi(CorrMapParam::Instance().lumiInst);

Detectors/TPC/spacecharge/include/TPCSpaceCharge/SpaceCharge.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,20 @@ class SpaceCharge
369369
void calcGlobalCorrWithGlobalDistIterative(const Side side, const SpaceCharge<DataT>* scSCale = nullptr, float scale = 0, const int maxIter = 100, const DataT approachZ = 1, const DataT approachR = 1, const DataT approachPhi = 1, const DataT diffCorr = 50e-6);
370370
void calcGlobalCorrWithGlobalDistIterative(const SpaceCharge<DataT>* scSCale = nullptr, float scale = 0, const int maxIter = 100, const DataT approachZ = 1, const DataT approachR = 1, const DataT approachPhi = 1, const DataT diffCorr = 50e-6);
371371

372+
/// Calculate global distortions using the global corrections by scaling with second distortion object, which will be consistent with scaled corrections in cartesian coordinates (as done in the tracking)
373+
/// \param side Side of the TPC
374+
/// \param scSCale possible second sc object
375+
/// \param scale scaling for second sc object
376+
void calcGlobalDistWithGlobalCorrIterativeLinearCartesian(const Side side, const SpaceCharge<DataT>* scSCale = nullptr, float scale = 0, const int maxIter = 100, const DataT approachX = 1, const DataT approachY = 1, const DataT approachZ = 1, const DataT diffCorr = 50e-6);
377+
void calcGlobalDistWithGlobalCorrIterativeLinearCartesian(const SpaceCharge<DataT>* scSCale = nullptr, float scale = 0, const int maxIter = 100, const DataT approachX = 1, const DataT approachY = 1, const DataT approachZ = 1, const DataT diffCorr = 50e-6);
378+
379+
/// Calculate global corrections using the global distortions by scaling with second distortion object, which will be consistent with scaled corrections in cartesian coordinates
380+
/// \param side Side of the TPC
381+
/// \param scSCale possible second sc object
382+
/// \param scale scaling for second sc object
383+
void calcGlobalCorrWithGlobalDistIterativeLinearCartesian(const Side side, const SpaceCharge<DataT>* scSCale = nullptr, float scale = 0, const int maxIter = 100, const DataT approachX = 1, const DataT approachY = 1, const DataT approachZ = 1, const DataT diffCorr = 50e-6);
384+
void calcGlobalCorrWithGlobalDistIterativeLinearCartesian(const SpaceCharge<DataT>* scSCale = nullptr, float scale = 0, const int maxIter = 100, const DataT approachX = 1, const DataT approachY = 1, const DataT approachZ = 1, const DataT diffCorr = 50e-6);
385+
372386
/// \return returns number of vertices in z direction
373387
unsigned short getNZVertices() const { return mParamGrid.NZVertices; }
374388

@@ -1373,6 +1387,7 @@ class SpaceCharge
13731387
void initRodAlignmentVoltages(const MisalignmentType misalignmentType, const FCType fcType, const int sector, const Side side, const float deltaPot);
13741388

13751389
void calcGlobalDistCorrIterative(const DistCorrInterpolator<DataT>& globCorr, const int maxIter, const DataT approachZ, const DataT approachR, const DataT approachPhi, const DataT diffCorr, const SpaceCharge<DataT>* scSCale, float scale, const Type type);
1390+
void calcGlobalDistCorrIterativeLinearCartesian(const DistCorrInterpolator<DataT>& globCorr, const int maxIter, const DataT approachX, const DataT approachY, const DataT approachZ, const DataT diffCorr, const SpaceCharge<DataT>* scSCale, float scale, const Type type);
13761391

13771392
ClassDefNV(SpaceCharge, 6);
13781393
};

Detectors/TPC/spacecharge/src/SpaceCharge.cxx

Lines changed: 177 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -757,15 +757,6 @@ void SpaceCharge<DataT>::calcGlobalDistCorrIterative(const DistCorrInterpolator<
757757
const DataT radius = getRVertex(iR, side);
758758
for (unsigned int iZ = 1; iZ < mParamGrid.NZVertices; ++iZ) {
759759
const DataT z = getZVertex(iZ, side);
760-
761-
unsigned int nearestiZ = iZ;
762-
unsigned int nearestiR = iR;
763-
unsigned int nearestiPhi = iPhi;
764-
765-
DataT nearestZ = getZVertex(nearestiZ, side);
766-
DataT nearestR = getRVertex(nearestiR, side);
767-
DataT nearestPhi = getPhiVertex(nearestiPhi, side);
768-
769760
//
770761
//==========================================================================================
771762
//==== start algorithm: use tricubic upsampling to numerically approach the query point ====
@@ -774,9 +765,9 @@ void SpaceCharge<DataT>::calcGlobalDistCorrIterative(const DistCorrInterpolator<
774765
// 1. calculate difference from nearest point to query point with stepwidth factor x
775766
// and approach the new point
776767
//
777-
DataT stepR = (radius - nearestR) * approachR;
778-
DataT stepZ = (z - nearestZ) * approachZ;
779-
DataT stepPhi = (phi - nearestPhi) * approachPhi;
768+
DataT stepR = 0;
769+
DataT stepZ = 0;
770+
DataT stepPhi = 0;
780771

781772
// needed to check for convergence
782773
DataT lastCorrdR = std::numeric_limits<DataT>::max();
@@ -790,9 +781,9 @@ void SpaceCharge<DataT>::calcGlobalDistCorrIterative(const DistCorrInterpolator<
790781

791782
for (int iter = 0; iter < maxIter; ++iter) {
792783
// 2. get new point coordinates
793-
const DataT rCurrPos = getRVertex(nearestiR, side) + stepR;
794-
const DataT zCurrPos = getZVertex(nearestiZ, side) + stepZ;
795-
const DataT phiCurrPos = getPhiVertex(nearestiPhi, side) + stepPhi;
784+
const DataT rCurrPos = radius + stepR;
785+
const DataT zCurrPos = z + stepZ;
786+
const DataT phiCurrPos = phi + stepPhi;
796787

797788
// abort calculation of drift path if electron reached inner/outer field cage or central electrode
798789
if (rCurrPos <= getRMinSim(side) || rCurrPos >= getRMaxSim(side) || getSide(zCurrPos) != side) {
@@ -867,6 +858,177 @@ void SpaceCharge<DataT>::calcGlobalDistCorrIterative(const DistCorrInterpolator<
867858
}
868859
}
869860

861+
template <typename DataT>
862+
void SpaceCharge<DataT>::calcGlobalDistWithGlobalCorrIterativeLinearCartesian(const Side side, const SpaceCharge<DataT>* scSCale, float scale, const int maxIter, const DataT approachX, const DataT approachY, const DataT approachZ, const DataT diffCorr)
863+
{
864+
calcGlobalDistCorrIterativeLinearCartesian(getGlobalCorrInterpolator(side), maxIter, approachX, approachY, approachZ, diffCorr, scSCale, scale, Type::Distortions);
865+
}
866+
867+
template <typename DataT>
868+
void SpaceCharge<DataT>::calcGlobalDistWithGlobalCorrIterativeLinearCartesian(const SpaceCharge<DataT>* scSCale, float scale, const int maxIter, const DataT approachX, const DataT approachY, const DataT approachZ, const DataT diffCorr)
869+
{
870+
#pragma omp parallel for num_threads(sNThreads)
871+
for (int iside = 0; iside < FNSIDES; ++iside) {
872+
const o2::tpc::Side side = (iside == 0) ? Side::A : Side::C;
873+
calcGlobalDistWithGlobalCorrIterativeLinearCartesian(side, scSCale, scale, maxIter, approachX, approachY, approachZ, diffCorr);
874+
}
875+
}
876+
877+
template <typename DataT>
878+
void SpaceCharge<DataT>::calcGlobalCorrWithGlobalDistIterativeLinearCartesian(const Side side, const SpaceCharge<DataT>* scSCale, float scale, const int maxIter, const DataT approachX, const DataT approachY, const DataT approachZ, const DataT diffCorr)
879+
{
880+
calcGlobalDistCorrIterativeLinearCartesian(getGlobalDistInterpolator(side), maxIter, approachX, approachY, approachZ, diffCorr, scSCale, scale, Type::Corrections);
881+
}
882+
883+
template <typename DataT>
884+
void SpaceCharge<DataT>::calcGlobalCorrWithGlobalDistIterativeLinearCartesian(const SpaceCharge<DataT>* scSCale, float scale, const int maxIter, const DataT approachX, const DataT approachY, const DataT approachZ, const DataT diffCorr)
885+
{
886+
#pragma omp parallel for num_threads(sNThreads)
887+
for (int iside = 0; iside < FNSIDES; ++iside) {
888+
const o2::tpc::Side side = (iside == 0) ? Side::A : Side::C;
889+
calcGlobalCorrWithGlobalDistIterativeLinearCartesian(side, scSCale, scale, maxIter, approachX, approachY, approachZ, diffCorr);
890+
}
891+
}
892+
893+
template <typename DataT>
894+
void SpaceCharge<DataT>::calcGlobalDistCorrIterativeLinearCartesian(const DistCorrInterpolator<DataT>& globCorr, const int maxIter, const DataT approachX, const DataT approachY, const DataT approachZ, const DataT diffCorr, const SpaceCharge<DataT>* scSCale, float scale, const Type type)
895+
{
896+
const Side side = globCorr.getSide();
897+
if (type == Type::Distortions) {
898+
initContainer(mGlobalDistdR[side], true);
899+
initContainer(mGlobalDistdZ[side], true);
900+
initContainer(mGlobalDistdRPhi[side], true);
901+
} else {
902+
initContainer(mGlobalCorrdR[side], true);
903+
initContainer(mGlobalCorrdZ[side], true);
904+
initContainer(mGlobalCorrdRPhi[side], true);
905+
}
906+
907+
const auto& scSCaleInterpolator = (type == Type::Distortions) ? scSCale->mInterpolatorGlobalCorr[side] : scSCale->mInterpolatorGlobalDist[side];
908+
909+
#pragma omp parallel for num_threads(sNThreads)
910+
for (unsigned int iPhi = 0; iPhi < mParamGrid.NPhiVertices; ++iPhi) {
911+
const DataT phi = getPhiVertex(iPhi, side);
912+
for (unsigned int iR = 0; iR < mParamGrid.NRVertices; ++iR) {
913+
const DataT radius = getRVertex(iR, side);
914+
const DataT x = getXFromPolar(radius, phi);
915+
const DataT y = getYFromPolar(radius, phi);
916+
917+
for (unsigned int iZ = 1; iZ < mParamGrid.NZVertices; ++iZ) {
918+
const DataT z = getZVertex(iZ, side);
919+
920+
DataT stepX = 0;
921+
DataT stepY = 0;
922+
DataT stepZ = 0;
923+
924+
// needed to check for convergence
925+
DataT lastCorrX = std::numeric_limits<DataT>::max();
926+
DataT lastCorrY = std::numeric_limits<DataT>::max();
927+
DataT lastCorrZ = std::numeric_limits<DataT>::max();
928+
DataT lastX = std::numeric_limits<DataT>::max();
929+
DataT lastY = std::numeric_limits<DataT>::max();
930+
DataT lastZ = std::numeric_limits<DataT>::max();
931+
932+
for (int iter = 0; iter < maxIter; ++iter) {
933+
const DataT xCurrPos = x + stepX;
934+
const DataT yCurrPos = y + stepY;
935+
const DataT zCurrPos = z + stepZ;
936+
937+
// abort calculation of drift path if electron reached inner/outer field cage or central electrode
938+
const DataT rCurrPos = getRadiusFromCartesian(xCurrPos, yCurrPos);
939+
if (rCurrPos <= getRMinSim(side) || rCurrPos >= getRMaxSim(side) || getSide(zCurrPos) != side) {
940+
break;
941+
}
942+
943+
// interpolate global correction at new point and calculate position of global correction
944+
DataT corrX = 0;
945+
DataT corrY = 0;
946+
DataT corrZ = 0;
947+
(type == Type::Distortions) ? getCorrections(xCurrPos, yCurrPos, zCurrPos, side, corrX, corrY, corrZ) : getDistortions(xCurrPos, yCurrPos, zCurrPos, side, corrX, corrY, corrZ);
948+
949+
if (scSCale && scale != 0) {
950+
DataT corrXScale = 0;
951+
DataT corrYScale = 0;
952+
DataT corrZScale = 0;
953+
(type == Type::Distortions) ? scSCale->getCorrections(xCurrPos, yCurrPos, zCurrPos, side, corrXScale, corrYScale, corrZScale) : getDistortions(xCurrPos, yCurrPos, zCurrPos, side, corrX, corrY, corrZ);
954+
corrX += scale * corrXScale;
955+
corrY += scale * corrYScale;
956+
corrZ += scale * corrZScale;
957+
}
958+
959+
// check for convergence
960+
const DataT diffCorrX = std::abs(corrX - lastCorrX);
961+
const DataT diffCorrY = std::abs(corrY - lastCorrY);
962+
const DataT diffCorrZ = std::abs(corrZ - lastCorrZ);
963+
964+
lastCorrX = corrX;
965+
lastCorrY = corrY;
966+
lastCorrZ = corrZ;
967+
lastX = xCurrPos;
968+
lastY = yCurrPos;
969+
lastZ = zCurrPos;
970+
971+
// stop algorithm if converged
972+
if ((diffCorrX < diffCorr) && (diffCorrY < diffCorr) && (diffCorrZ < diffCorr)) {
973+
break;
974+
}
975+
976+
const DataT xNewPos = xCurrPos + corrX;
977+
const DataT yNewPos = yCurrPos + corrY;
978+
const DataT zNewPos = zCurrPos + corrZ;
979+
980+
// approach desired coordinate
981+
stepX += (x - xNewPos) * approachX;
982+
stepY += (y - yNewPos) * approachY;
983+
stepZ += (z - zNewPos) * approachZ;
984+
}
985+
986+
const DataT xNew = lastX + lastCorrX;
987+
const DataT yNew = lastY + lastCorrY;
988+
const DataT radiusNew = getRadiusFromCartesian(xNew, yNew);
989+
const DataT corrdR = -(radiusNew - getRadiusFromCartesian(lastX, lastY));
990+
991+
float phiNew = getPhiFromCartesian(xNew, yNew);
992+
o2::math_utils::bringTo02PiGen(phiNew);
993+
994+
float phiLast = getPhiFromCartesian(lastX, lastY);
995+
o2::math_utils::bringTo02PiGen(phiLast);
996+
997+
DataT deltaPhi = (phiNew - phiLast);
998+
// handle edge cases
999+
if (deltaPhi > PI) {
1000+
deltaPhi -= 2 * PI;
1001+
} else if (deltaPhi < -PI) {
1002+
deltaPhi += 2 * PI;
1003+
}
1004+
const DataT corrdRPhi = -deltaPhi * radiusNew;
1005+
1006+
// set global distortions if algorithm converged or iterations exceed max numbers of iterations
1007+
if (type == Type::Distortions) {
1008+
mGlobalDistdR[side](iZ, iR, iPhi) = corrdR;
1009+
mGlobalDistdRPhi[side](iZ, iR, iPhi) = corrdRPhi;
1010+
mGlobalDistdZ[side](iZ, iR, iPhi) = -lastCorrZ;
1011+
} else {
1012+
mGlobalCorrdR[side](iZ, iR, iPhi) = corrdR;
1013+
mGlobalCorrdRPhi[side](iZ, iR, iPhi) = corrdRPhi;
1014+
mGlobalCorrdZ[side](iZ, iR, iPhi) = -lastCorrZ;
1015+
}
1016+
}
1017+
}
1018+
for (unsigned int iR = 0; iR < mParamGrid.NRVertices; ++iR) {
1019+
if (type == Type::Distortions) {
1020+
mGlobalDistdR[side](0, iR, iPhi) = 3 * (mGlobalDistdR[side](1, iR, iPhi) - mGlobalDistdR[side](2, iR, iPhi)) + mGlobalDistdR[side](3, iR, iPhi);
1021+
mGlobalDistdRPhi[side](0, iR, iPhi) = 3 * (mGlobalDistdRPhi[side](1, iR, iPhi) - mGlobalDistdRPhi[side](2, iR, iPhi)) + mGlobalDistdRPhi[side](3, iR, iPhi);
1022+
mGlobalDistdZ[side](0, iR, iPhi) = 3 * (mGlobalDistdZ[side](1, iR, iPhi) - mGlobalDistdZ[side](2, iR, iPhi)) + mGlobalDistdZ[side](3, iR, iPhi);
1023+
} else {
1024+
mGlobalCorrdR[side](0, iR, iPhi) = 3 * (mGlobalCorrdR[side](1, iR, iPhi) - mGlobalCorrdR[side](2, iR, iPhi)) + mGlobalCorrdR[side](3, iR, iPhi);
1025+
mGlobalCorrdRPhi[side](0, iR, iPhi) = 3 * (mGlobalCorrdRPhi[side](1, iR, iPhi) - mGlobalCorrdRPhi[side](2, iR, iPhi)) + mGlobalCorrdRPhi[side](3, iR, iPhi);
1026+
mGlobalCorrdZ[side](0, iR, iPhi) = 3 * (mGlobalCorrdZ[side](1, iR, iPhi) - mGlobalCorrdZ[side](2, iR, iPhi)) + mGlobalCorrdZ[side](3, iR, iPhi);
1027+
}
1028+
}
1029+
}
1030+
}
1031+
8701032
template <typename DataT>
8711033
NumericalFields<DataT> SpaceCharge<DataT>::getElectricFieldsInterpolator(const Side side) const
8721034
{

0 commit comments

Comments
 (0)