Skip to content

Commit a2183b1

Browse files
TPC space-charge: Improve GEM frame charging-up distortions
Adding: - downsampling of space-charge objects - simulation of n-sectors only - some helper functions - weighted filling of charging-up of GEM frames for smoother potential - set global distortions from function
1 parent e12ca36 commit a2183b1

File tree

6 files changed

+259
-93
lines changed

6 files changed

+259
-93
lines changed

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,9 @@ struct DataContainer3D {
186186
/// print the matrix
187187
void print() const;
188188

189+
/// convert a data container to a new datacontainer with different grid definition (e.g. different number of vertices)
190+
DataContainer3D<DataT> convert(const o2::tpc::RegularGrid3D<DataT>& gridNew, const o2::tpc::RegularGrid3D<DataT>& gridRef, const int threads = 1) const;
191+
189192
/// operator overload
190193
DataContainer3D<DataT>& operator*=(const DataT value);
191194
DataContainer3D<DataT>& operator+=(const DataContainer3D<DataT>& other);

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#define ALICEO2_TPC_POISSONSOLVERHELPERS_H_
2020

2121
#include "CommonConstants/MathConstants.h"
22+
#include "DataFormatsTPC/Defs.h"
2223

2324
namespace o2
2425
{
@@ -55,7 +56,7 @@ struct MGParameters { ///< Parameter
5556
inline static int nMGCycle = 200; ///< number of multi grid cycle (V type)
5657
inline static int maxLoop = 7; ///< the number of tree-deep of multi grid
5758
inline static int gamma = 1; ///< number of iteration at coarsest level !TODO SET TO REASONABLE VALUE!
58-
inline static bool normalizeGridToOneSector = false; ///< the grid in phi direction is squashed from 2 Pi to (2 Pi / SECTORSPERSIDE). This can used to get the potential for phi symmetric sc density or boundary potentials
59+
inline static int normalizeGridToNSector = SECTORSPERSIDE; ///< the grid in phi direction is squashed from 2 Pi to (2 Pi / SECTORSPERSIDE). This can used to get the potential for phi symmetric sc density or boundary potentials
5960
};
6061

6162
template <typename DataT = double>

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

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -204,10 +204,13 @@ class SpaceCharge
204204

205205
/// simulate only one sector instead of 18 per side. This makes currently only sense for the static distortions (ToDo: simplify usage)
206206
/// phi max will be restricted to 2Pi/18 for this instance and for global instance of poisson solver
207-
void setSimOneSector();
207+
void setSimOneSector() { setSimNSector(1); }
208+
209+
/// simulate N sectors
210+
void setSimNSector(const int nSectors);
208211

209212
/// unsetting simulation of one sector
210-
static void unsetSimOneSector();
213+
static void unsetSimNSector();
211214

212215
/// setting default potential (same potential for all GEM frames. The default value of 1000V are matched to distortions observed in laser data without X-Ray etc.
213216
/// \param side side of the TPC where the potential will be set
@@ -308,10 +311,24 @@ class SpaceCharge
308311
/// scaling the space-charge density for given stack
309312
void scaleChargeDensityStack(const float scalingFactor, const Sector sector, const GEMstack stack);
310313

314+
/// scale the potential by a scaling factor
315+
/// \param scalingFactor factor to scale the potential
316+
/// \param side side for which the potential will be scaled
317+
void scalePotential(const DataT scalingFactor, const Side side) { mPotential[side] *= scalingFactor; }
318+
311319
/// add space charge density from other object (this.mDensity = this.mDensity + other.mDensity)
312320
/// \param otherSC other space-charge object, which charge will be added to current object
313321
void addChargeDensity(const SpaceCharge<DataT>& otherSC);
314322

323+
/// add global corrections from other space charge object
324+
void addGlobalCorrections(const SpaceCharge<DataT>& otherSC, const Side side);
325+
326+
/// convert space-charge object to new definition of number of vertices
327+
/// \param nZNew new number of vertices in z direction
328+
/// \param nRNew new number of vertices in r direction
329+
/// \param nPhiNew new number of vertices in phi direction
330+
void downSampleObject(const int nZNew, const int nRNew, const int nPhiNew);
331+
315332
/// step 3: calculate the local distortions and corrections with an electric field
316333
/// \param type calculate local corrections or local distortions: type = o2::tpc::SpaceCharge<>::Type::Distortions or o2::tpc::SpaceCharge<>::Type::Corrections
317334
/// \param formulaStruct struct containing a method to evaluate the electric field Er, Ez, Ephi (analytical formula or by TriCubic interpolator)
@@ -415,6 +432,9 @@ class SpaceCharge
415432
/// \param phi global phi coordinate
416433
DataT getDensityCyl(const DataT z, const DataT r, const DataT phi, const Side side) const;
417434

435+
/// get the potential for list of given coordinate
436+
std::vector<float> getDensityCyl(const std::vector<DataT>& z, const std::vector<DataT>& r, const std::vector<DataT>& phi, const Side side) const;
437+
418438
/// get the potential for given coordinate
419439
/// \param z global z coordinate
420440
/// \param r global r coordinate
@@ -1184,6 +1204,10 @@ class SpaceCharge
11841204
/// \param gCorr function returning global corrections for given global coordinate
11851205
void setGlobalCorrections(const std::function<void(int sector, DataT gx, DataT gy, DataT gz, DataT& gCx, DataT& gCy, DataT& gCz)>& gCorr, const Side side);
11861206

1207+
/// setting the global distortions directly from input function provided in global coordinates
1208+
/// \param gDist function returning global distortions for given global coordinate
1209+
void setGlobalDistortions(const std::function<void(int sector, DataT gx, DataT gy, DataT gz, DataT& gCx, DataT& gCy, DataT& gCz)>& gDist, const Side side);
1210+
11871211
/// set misalignment of ROC for shift in z
11881212
/// \param sector sector for which the misalignment in z will be applied (if sector=-1 all sectors are shifted)
11891213
/// \param type 0=IROC, 1=OROC, 2=IROC+OROC
@@ -1229,7 +1253,16 @@ class SpaceCharge
12291253
/// \param tgl tgl of the track
12301254
/// \param nPoints number of points used to calculate the DCAr
12311255
/// \param pcstream if provided debug output is being created
1232-
float getDCAr(float tgl, const int nPoints, const float phi, o2::utils::TreeStreamRedirector* pcstream = nullptr) const;
1256+
float getDCAr(float tgl, const int nPoints, const float phi, float rStart = -1, o2::utils::TreeStreamRedirector* pcstream = nullptr) const;
1257+
1258+
/// \return returns nearest phi vertex for given phi position
1259+
size_t getNearestPhiVertex(const DataT phi, const Side side) const { return std::round(phi / getGridSpacingPhi(side)); }
1260+
1261+
/// \return returns nearest r vertex for given radius position
1262+
size_t getNearestRVertex(const DataT r, const Side side) const { return std::round((r - getRMin(side)) / getGridSpacingR(side) + 0.5); }
1263+
1264+
/// \return returns number of bins in phi direction for the gap between sectors and for the GEM frame
1265+
size_t getPhiBinsGapFrame(const Side side) const;
12331266

12341267
private:
12351268
ParamSpaceCharge mParamGrid{}; ///< parameters of the grid on which the calculations are performed
@@ -1352,15 +1385,6 @@ class SpaceCharge
13521385
/// dump the created electron tracks with calculateElectronDriftPath function to a tree
13531386
void dumpElectronTracksToTree(const std::vector<std::pair<std::vector<o2::math_utils::Point3D<float>>, std::array<DataT, 3>>>& electronTracks, const int nSamplingPoints, const char* outFile) const;
13541387

1355-
/// \return returns nearest phi vertex for given phi position
1356-
size_t getNearestPhiVertex(const DataT phi, const Side side) const { return std::round(phi / getGridSpacingPhi(side)); }
1357-
1358-
/// \return returns nearest r vertex for given radius position
1359-
size_t getNearestRVertex(const DataT r, const Side side) const { return std::round((r - getRMin(side)) / getGridSpacingR(side) + 0.5); }
1360-
1361-
/// \return returns number of bins in phi direction for the gap between sectors and for the GEM frame
1362-
size_t getPhiBinsGapFrame(const Side side) const;
1363-
13641388
/// \return setting the boundary potential for given GEM stack
13651389
void setPotentialBoundaryGEMFrameAlongPhi(const std::function<DataT(DataT)>& potentialFunc, const GEMstack stack, const bool bottom, const Side side, const bool outerFrame = false);
13661390

@@ -1372,23 +1396,25 @@ class SpaceCharge
13721396

13731397
void initAllBuffers();
13741398

1375-
void setBoundaryFromIndices(const std::function<DataT(DataT)>& potentialFunc, const std::vector<size_t>& indices, const Side side);
1399+
void setBoundaryFromIndices(const std::function<DataT(DataT)>& potentialFunc, const std::vector<std::pair<size_t, float>>& indices, const Side side);
13761400

13771401
/// get indices of the GEM frame along r
1378-
std::vector<size_t> getPotentialBoundaryGEMFrameAlongRIndices(const Side side) const;
1402+
std::vector<std::pair<size_t, float>> getPotentialBoundaryGEMFrameAlongRIndices(const Side side) const;
13791403

13801404
/// get indices of the GEM frame along phi
1381-
std::vector<size_t> getPotentialBoundaryGEMFrameAlongPhiIndices(const GEMstack stack, const bool bottom, const Side side, const bool outerFrame, const bool noGap = false) const;
1405+
std::vector<std::pair<size_t, float>> getPotentialBoundaryGEMFrameAlongPhiIndices(const GEMstack stack, const bool bottom, const Side side, const bool outerFrame, const bool noGap = false) const;
13821406

13831407
void setROCMisalignment(int stackType, int misalignmentType, int sector, const float potMin, const float potMax);
1384-
void fillROCMisalignment(const std::vector<size_t>& indicesTop, const std::vector<size_t>& indicesBottom, int sector, int misalignmentType, const std::pair<float, float>& deltaPotPar);
1408+
void fillROCMisalignment(const std::vector<std::pair<size_t, float>>& indicesTop, const std::vector<std::pair<size_t, float>>& indicesBottom, int sector, int misalignmentType, const std::pair<float, float>& deltaPotPar);
13851409

13861410
/// set potentialsdue to ROD misalignment
13871411
void initRodAlignmentVoltages(const MisalignmentType misalignmentType, const FCType fcType, const int sector, const Side side, const float deltaPot);
13881412

13891413
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);
13901414
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);
13911415

1416+
void setGlobalDistCorr(const Type type, const std::function<void(int sector, DataT gx, DataT gy, DataT gz, DataT& gCx, DataT& gCy, DataT& gCz)>& gFunc, const Side side);
1417+
13921418
ClassDefNV(SpaceCharge, 6);
13931419
};
13941420

Detectors/TPC/spacecharge/src/DataContainer3D.cxx

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,6 @@ void DataContainer3D<DataT>::dumpSlice(std::string_view treename, std::string_vi
331331
ROOT::RDataFrame dFrame(treename, fileIn);
332332

333333
auto df = dFrame.Define("slice", [rangeiZ, rangeiR, rangeiPhi](const std::pair<long, std::vector<float>>& values, unsigned short nz, unsigned short nr, unsigned short nphi) {
334-
const bool simOneSectorOnly = MGParameters::normalizeGridToOneSector;
335334
std::vector<size_t> ir;
336335
std::vector<size_t> iphi;
337336
std::vector<size_t> iz;
@@ -370,12 +369,12 @@ void DataContainer3D<DataT>::dumpSlice(std::string_view treename, std::string_vi
370369

371370
const float rTmp = o2::tpc::GridProperties<float>::getRMin() + o2::tpc::GridProperties<float>::getGridSpacingR(nr) * iRTmp;
372371
const float zTmp = o2::tpc::GridProperties<float>::getZMin() + o2::tpc::GridProperties<float>::getGridSpacingZ(nz) * iZTmp;
373-
const float phiTmp = o2::tpc::GridProperties<float>::getPhiMin() + o2::tpc::GridProperties<float>::getGridSpacingPhi(nphi) / (simOneSectorOnly ? SECTORSPERSIDE : 1) * iPhiTmp;
372+
const float phiTmp = o2::tpc::GridProperties<float>::getPhiMin() + o2::tpc::GridProperties<float>::getGridSpacingPhi(nphi) * (MGParameters::normalizeGridToNSector / double(SECTORSPERSIDE)) * iPhiTmp;
374373

375374
const float x = rTmp * std::cos(phiTmp);
376375
const float y = rTmp * std::sin(phiTmp);
377376
const LocalPosition3D pos(x, y, zTmp);
378-
unsigned char secNum = simOneSectorOnly ? 0 : std::floor(phiTmp / SECPHIWIDTH);
377+
unsigned char secNum = std::floor(phiTmp / SECPHIWIDTH);
379378
Sector sector(secNum + (pos.Z() < 0) * SECTORSPERSIDE);
380379
LocalPosition3D lPosTmp = Mapper::GlobalToLocal(pos, sector);
381380

@@ -428,10 +427,9 @@ void DataContainer3D<DataT>::dumpInterpolation(std::string_view treename, std::s
428427

429428
// define grid for interpolation
430429
using GridProp = GridProperties<DataT>;
431-
const RegularGrid3D<DataT> mGrid3D(GridProp::ZMIN, GridProp::RMIN, GridProp::PHIMIN, GridProp::getGridSpacingZ(nz), GridProp::getGridSpacingR(nr), o2::tpc::GridProperties<float>::getGridSpacingPhi(nphi) / (MGParameters::normalizeGridToOneSector ? SECTORSPERSIDE : 1), ParamSpaceCharge{nr, nz, nphi});
430+
const RegularGrid3D<DataT> mGrid3D(GridProp::ZMIN, GridProp::RMIN, GridProp::PHIMIN, GridProp::getGridSpacingZ(nz), GridProp::getGridSpacingR(nr), o2::tpc::GridProperties<float>::getGridSpacingPhi(nphi) * (MGParameters::normalizeGridToNSector / double(SECTORSPERSIDE)), ParamSpaceCharge{nr, nz, nphi});
432431

433432
auto interpolate = [&mGrid3D = std::as_const(mGrid3D), &data = std::as_const(data), rangeR, rangeZ, rangePhi, nR, nZ, nPhi](unsigned int, ULong64_t iPhi) {
434-
const bool simOneSectorOnly = MGParameters::normalizeGridToOneSector;
435433
std::vector<size_t> ir;
436434
std::vector<size_t> iphi;
437435
std::vector<size_t> iz;
@@ -473,7 +471,7 @@ void DataContainer3D<DataT>::dumpInterpolation(std::string_view treename, std::s
473471
const float x = rPos * std::cos(phiPos);
474472
const float y = rPos * std::sin(phiPos);
475473
const LocalPosition3D pos(x, y, zPos);
476-
unsigned char secNum = simOneSectorOnly ? 0 : std::floor(phiPos / SECPHIWIDTH);
474+
unsigned char secNum = std::floor(phiPos / SECPHIWIDTH); // TODO CHECK THIS
477475
Sector sector(secNum + (pos.Z() < 0) * SECTORSPERSIDE);
478476
LocalPosition3D lPosTmp = Mapper::GlobalToLocal(pos, sector);
479477
lPos.emplace_back(lPosTmp);
@@ -512,6 +510,27 @@ bool DataContainer3D<DataT>::getVertices(std::string_view treename, std::string_
512510
return true;
513511
}
514512

513+
template <typename DataT>
514+
DataContainer3D<DataT> DataContainer3D<DataT>::convert(const o2::tpc::RegularGrid3D<DataT>& gridNew, const o2::tpc::RegularGrid3D<DataT>& gridRef, const int threads) const
515+
{
516+
const int nZNew = gridNew.getNZ();
517+
const int nRNew = gridNew.getNR();
518+
const int nPhiNew = gridNew.getNPhi();
519+
DataContainer3D<DataT> contCont(nZNew, nRNew, nPhiNew);
520+
#pragma omp parallel for num_threads(threads)
521+
for (size_t iPhi = 0; iPhi < nPhiNew; ++iPhi) {
522+
const DataT phi = gridNew.getPhiVertex(iPhi);
523+
for (size_t iR = 0; iR < nRNew; ++iR) {
524+
const DataT radius = gridNew.getRVertex(iR);
525+
for (size_t iZ = 0; iZ < nZNew; ++iZ) {
526+
const DataT z = gridNew.getZVertex(iZ);
527+
contCont(iZ, iR, iPhi) = interpolate(z, radius, phi, gridRef);
528+
}
529+
}
530+
}
531+
return contCont;
532+
}
533+
515534
template class o2::tpc::DataContainer3D<float>;
516535
template class o2::tpc::DataContainer3D<double>;
517536

Detectors/TPC/spacecharge/src/PoissonSolver.cxx

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -940,7 +940,7 @@ void PoissonSolver<DataT>::residue2D(Vector& residue, const Vector& matricesCurr
940940
for (int j = 1; j < tnZColumn - 1; ++j) {
941941
residue(i, j, iPhi) = ih2 * (coefficient1[i] * matricesCurrentV(i + 1, j, iPhi) + coefficient2[i] * matricesCurrentV(i - 1, j, iPhi) + tempRatio * (matricesCurrentV(i, j + 1, iPhi) + matricesCurrentV(i, j - 1, iPhi)) - inverseTempFourth * matricesCurrentV(i, j, iPhi)) + matricesCurrentCharge(i, j, iPhi);
942942
} // end cols
943-
} // end nRRow
943+
} // end nRRow
944944

945945
// Boundary points.
946946
for (int i = 0; i < tnRRow; ++i) {
@@ -997,7 +997,7 @@ void PoissonSolver<DataT>::residue3D(Vector& residue, const Vector& matricesCurr
997997
coefficient3[i] * (signPlus * matricesCurrentV(i, j, mp1) + signMinus * matricesCurrentV(i, j, mm1)) - inverseCoefficient4[i] * matricesCurrentV(i, j, m)) +
998998
matricesCurrentCharge(i, j, m);
999999
} // end cols
1000-
} // end mParamGrid.NRVertices
1000+
} // end mParamGrid.NRVertices
10011001
}
10021002
}
10031003

@@ -1263,9 +1263,9 @@ void PoissonSolver<DataT>::relax3D(Vector& matricesCurrentV, const Vector& matri
12631263
for (int i = isw; i < tnRRow - 1; i += 2) {
12641264
(matricesCurrentV)(i, j, m) = (coefficient2[i] * (matricesCurrentV)(i - 1, j, m) + tempRatioZ * ((matricesCurrentV)(i, j - 1, m) + (matricesCurrentV)(i, j + 1, m)) + coefficient1[i] * (matricesCurrentV)(i + 1, j, m) + coefficient3[i] * (signPlus * (matricesCurrentV)(i, j, mp1) + signMinus * (matricesCurrentV)(i, j, mm1)) + (h2 * (matricesCurrentCharge)(i, j, m))) * coefficient4[i];
12651265
} // end cols
1266-
} // end mParamGrid.NRVertices
1267-
} // end phi
1268-
} // end sweep
1266+
} // end mParamGrid.NRVertices
1267+
} // end phi
1268+
} // end sweep
12691269
} else if (MGParameters::relaxType == RelaxType::Jacobi) {
12701270
// for each slice
12711271
for (int m = 0; m < iPhi; ++m) {
@@ -1306,8 +1306,8 @@ void PoissonSolver<DataT>::relax3D(Vector& matricesCurrentV, const Vector& matri
13061306
for (int i = 1; i < tnRRow - 1; ++i) {
13071307
(matricesCurrentV)(i, j, m) = (coefficient2[i] * (matricesCurrentV)(i - 1, j, m) + tempRatioZ * ((matricesCurrentV)(i, j - 1, m) + (matricesCurrentV)(i, j + 1, m)) + coefficient1[i] * (matricesCurrentV)(i + 1, j, m) + coefficient3[i] * (signPlus * (matricesCurrentV)(i, j, mp1) + signMinus * (matricesCurrentV)(i, j, mm1)) + (h2 * (matricesCurrentCharge)(i, j, m))) * coefficient4[i];
13081308
} // end cols
1309-
} // end mParamGrid.NRVertices
1310-
} // end phi
1309+
} // end mParamGrid.NRVertices
1310+
} // end phi
13111311
} else {
13121312
// Case weighted Jacobi
13131313
// TODO
@@ -1329,15 +1329,15 @@ void PoissonSolver<DataT>::relax2D(Vector& matricesCurrentV, const Vector& matri
13291329
matricesCurrentV(i, j, iPhi) = tempFourth * (coefficient1[i] * matricesCurrentV(i + 1, j, iPhi) + coefficient2[i] * matricesCurrentV(i - 1, j, iPhi) +
13301330
tempRatio * (matricesCurrentV(i, j + 1, iPhi) + matricesCurrentV(i, j - 1, iPhi)) + (h2 * matricesCurrentCharge(i, j, iPhi)));
13311331
} // end cols
1332-
} // end mParamGrid.NRVertices
1333-
} // end pass red-black
1332+
} // end mParamGrid.NRVertices
1333+
} // end pass red-black
13341334
} else if (MGParameters::relaxType == RelaxType::Jacobi) {
13351335
for (int j = 1; j < tnZColumn - 1; ++j) {
13361336
for (int i = 1; i < tnRRow - 1; ++i) {
13371337
matricesCurrentV(i, j, iPhi) = tempFourth * (coefficient1[i] * matricesCurrentV(i + 1, j, iPhi) + coefficient2[i] * matricesCurrentV(i - 1, j, iPhi) +
13381338
tempRatio * (matricesCurrentV(i, j + 1, iPhi) + matricesCurrentV(i, j - 1, iPhi)) + (h2 * matricesCurrentCharge(i, j, iPhi)));
13391339
} // end cols
1340-
} // end mParamGrid.NRVertices
1340+
} // end mParamGrid.NRVertices
13411341
} else if (MGParameters::relaxType == RelaxType::WeightedJacobi) {
13421342
// Weighted Jacobi
13431343
// TODO
@@ -1421,7 +1421,7 @@ void PoissonSolver<DataT>::restrict3D(Vector& matricesCurrentCharge, const Vecto
14211421

14221422
matricesCurrentCharge(i, j, m) = residue(ii, jj, mm) / 8 + s1 / 16 + s2 / 32 + s3 / 64;
14231423
} // end cols
1424-
} // end mParamGrid.NRVertices
1424+
} // end mParamGrid.NRVertices
14251425

14261426
// for boundary
14271427
for (int j = 0, jj = 0; j < tnZColumn; ++j, jj += 2) {
@@ -1460,7 +1460,7 @@ void PoissonSolver<DataT>::restrict2D(Vector& matricesCurrentCharge, const Vecto
14601460
(residue(iip1, jjp1, iphi) + residue(iim1, jjp1, iphi) + residue(iip1, jjm1, iphi) + residue(iim1, jjm1, iphi)) / 16;
14611461
}
14621462
} // end cols
1463-
} // end mParamGrid.NRVertices
1463+
} // end mParamGrid.NRVertices
14641464
// boundary
14651465
// for boundary
14661466
for (int j = 0, jj = 0; j < tnZColumn; ++j, jj += 2) {
@@ -1520,7 +1520,7 @@ void PoissonSolver<DataT>::calcCoefficients2D(unsigned int from, unsigned int to
15201520
template <typename DataT>
15211521
DataT PoissonSolver<DataT>::getGridSizePhiInv()
15221522
{
1523-
return MGParameters::normalizeGridToOneSector ? (INVTWOPI * SECTORSPERSIDE) : INVTWOPI;
1523+
return INVTWOPI * SECTORSPERSIDE / MGParameters::normalizeGridToNSector;
15241524
}
15251525

15261526
template class o2::tpc::PoissonSolver<double>;

0 commit comments

Comments
 (0)