18#ifndef GPUCA_ALIGPUCODE
28MatLayerCyl::MatLayerCyl() : mNZBins(0), mNPhiBins(0), mNPhiSlices(0), mZHalf(0.f), mRMin2(0.f), mRMax2(0.f), mDZ(0.f), mDZInv(0.f), mDPhi(0.f), mDPhiInv(0.f), mPhiBin2Slice(nullptr), mSliceCos(nullptr), mSliceSin(nullptr), mCells(nullptr)
33#ifndef GPUCA_ALIGPUCODE
48 if (drphiMin < 0.001f) {
52 int nz = 2 * zHalfSpan / dzMin, nphi = peri / drphiMin;
53 initSegmentation(rMin, rMax, zHalfSpan, nz < 1 ? 1 : nz, nphi < 1 ? 1 : nphi);
78 mDZ = 2. * zHalfSpan / nz;
89 for (
int i = nphi;
i--;) {
101 for (
int i = nphi;
i--;) {
102 mSliceCos[
i] = o2::math_utils::cos(getPhiBinMin(
i));
103 mSliceSin[
i] = o2::math_utils::sin(getPhiBinMin(
i));
117 ntrPerCell = ntrPerCell > 1 ? ntrPerCell : 1;
118 for (
int iz = getNZBins(); iz--;) {
119 for (
int ip = getNPhiBins(); ip--;) {
130 float zmn = getZBinMin(iz), phmn = getPhiBinMin(ip), sn, cs, rMin = getRMin(), rMax = getRMax();
131 double meanRho = 0., meanX2X0 = 0., lgt = 0.;
133 float dz = getDZ() / ntrPerCell;
134 for (
int isz = ntrPerCell; isz--;) {
135 float zs = zmn + (isz + 0.5) * dz;
136 float dzt = zs > 0.f ? 0.25 * dz : -0.25 * dz;
137 for (
int isp = ntrPerCell; isp--;) {
138 o2::math_utils::sincos(phmn + (isp + 0.5) * getDPhi() / ntrPerCell, sn, cs);
143#ifdef O2_WITH_VECGEOM
144 bud = o2::base::GeometryManager::vecGeomMaterialBudget(rMin * cs, rMin * sn, zs - dzt, rMax * cs, rMax * sn, zs + dzt);
146 LOG(fatal) <<
"MatbudGeomBackend::VECGEOM requested but O2 was built without VecGeom support (TGeo2VecGeom not found at configure time)";
157 auto& cell =
mCells[getCellIDPhiBin(ip, iz)];
159 cell.meanX2X0 = meanX2X0 / lgt;
166 if (std::abs(
i -
j) > 1 ||
i ==
j || std::max(
i,
j) >= getNPhiSlices()) {
167 LOG(error) <<
"Only existing " << getNPhiSlices() <<
" slices with diff. of 1 can be merged, input is " <<
i <<
" and " <<
j;
171 for (
int iz = getNZBins(); iz--;) {
175 if (++ndiff > maxDifferent) {
189 if (rav > 0 && std::abs(rdf / rav) > maxRelDiff) {
192 if (xav > 0 && std::abs(xdf / xav) > maxRelDiff) {
202 if (getNPhiSlices() < getNPhiBins()) {
203 LOG(error) << getNPhiBins() <<
" phi bins were already merged to " << getNPhiSlices() <<
" slices";
207 std::vector<int> phi2SlNew(getNPhiBins());
208 for (
int i = 0;
i < getNPhiBins();
i++) {
211 for (
int is = 1; is < getNPhiSlices(); is++) {
217 phi2SlNew[is] = newSl;
219 if (newSl + 1 == getNPhiSlices()) {
223 int slMin = 0, slMax = 0, is = 0;
224 while (is++ < getNPhiSlices()) {
225 while (is < getNPhiSlices() && phi2SlNew[is] == newSl) {
229 if (slMax > slMin || newSl != slMin) {
232 float norm = 1.f / (1.f + slMax - slMin);
233 for (
int iz = getNZBins(); iz--;) {
234 int iDest = newSl * getNZBins() + iz, iSrc = slMin * getNZBins() + iz;
236 for (
int ism = slMin + 1; ism <= slMax; ism++) {
237 iSrc = ism * getNZBins() + iz;
241 mCells[iDest].scale(norm);
243 LOG(info) <<
"mapping " << slMin <<
":" << slMax <<
" to new slice " << newSl;
248 for (
int i = 0;
i < getNPhiBins();
i++) {
262 LOG(info) <<
"Updated Nslices = " << getNPhiSlices();
269 mean.meanRho = rms.
meanRho = 0.f;
271 for (
int ip = getNPhiBins(); ip--;) {
272 for (
int iz = getNZBins(); iz--;) {
274 mean.meanRho += cell.meanRho;
275 mean.meanX2X0 += cell.meanX2X0;
276 rms.
meanRho += cell.meanRho * cell.meanRho;
277 rms.
meanX2X0 += cell.meanX2X0 * cell.meanX2X0;
280 int nc = getNPhiBins() * getNZBins();
285 rms.
meanRho -= mean.meanRho * mean.meanRho;
286 rms.
meanX2X0 -= mean.meanX2X0 * mean.meanX2X0;
295 float szkb = float(getFlatBufferSize()) / 1024;
296 printf(
"Cyl.Layer %.3f<r<%.3f %+.3f<Z<%+.3f | Nphi: %5d (%d slices) Nz: %5d Size: %.3f KB\n",
297 getRMin(), getRMax(), getZMin(), getZMax(), getNPhiBins(), getNPhiSlices(), getNZBins(), szkb);
301 for (
int ip = 0; ip < getNPhiSlices(); ip++) {
303 int nb = getNPhiBinsInSlice(ip, ib0, ib1);
304 printf(
"phi slice: %d (%d bins %d-%d %.4f:%.4f) sn:%+.4f/cs:%+.4f ... [iz/<rho>/<x/x0>] \n",
305 ip, nb, ib0, ib1, getDPhi() * ib0, getDPhi() * (ib1 + 1), getSliceSin(ip), getSliceCos(ip));
306 for (
int iz = 0; iz < getNZBins(); iz++) {
308 printf(
"%3d/%.2e/%.2e ", iz, cell.meanRho, cell.meanX2X0);
309 if (((iz + 1) % 5) == 0) {
313 if (getNZBins() % 5) {
334 LOGP(info,
"Scaling layer {:.3f}<r<{:.3f} by {:.3f}", getRMin(), getRMax(), factor);
365 binMin = binMax = -1;
366 for (
int ib = getNPhiBins(); ib--;) {
367 if (phiBin2Slice(ib) == iSlice) {
368 binMax < 0 ? binMin = binMax = ib : binMin = ib;
General auxilliary methods.
Definition of the GeometryManager class.
Declarations for single cylindrical material layer class.
static o2::base::MatBudget meanMaterialBudget(float x0, float y0, float z0, float x1, float y1, float z1, TGeoNavigator *nav=nullptr)
short mNPhiSlices
actual number of phi slices
MatCell * mCells
cached sin each phi slice
short mNPhiBins
number of phi bins (logical)
void optimizePhiSlices(float maxRelDiff=0.05)
float mRMin2
squared min r
std::size_t estimateFlatBufferSize() const
float mDZ
Z slice thickness.
void populateFromTGeo(int ntrPerCell=10, MatbudGeomBackend backend=MatbudGeomBackend::ROOT)
float mDPhi
phi slice thickness
static constexpr size_t getBufferAlignmentBytes()
Gives minimal alignment in bytes required for the flat buffer.
void print(bool data=false) const
float * mSliceSin
cached cos each phi slice
void initSegmentation(float rMin, float rMax, float zHalfSpan, int nz, int nphi)
bool cellsDiffer(const MatCell &cellA, const MatCell &cellB, float maxRelDiff) const
float mDZInv
Z slice thickness inverse.
void getMeanRMS(MatCell &mean, MatCell &rms) const
float * mSliceCos
mapping from analytical phi bin ID to real slice ID
void flatten(char *newPtr)
void scale(float factor, bool _x2x0=true, bool _rho=true)
short mNZBins
number of Z bins
MatCell & getCellPhiBin(int iphi, int iz)
float mRMax2
squared max r
void fixPointers(char *oldPtr, char *newPtr)
float mDPhiInv
phi slice thickness inverse
bool canMergePhiSlices(int i, int j, float maxRelDiff=0.05, int maxDifferent=1) const
uint32_t mConstructionMask
mask for constructed object members, first two bytes are used by this class
int32_t mFlatBufferSize
size of the flat buffer
char * mFlatBufferContainer
static T * relocatePointer(const char *oldBase, char *newBase, const T *ptr)
Relocates a pointer inside a buffer to the new buffer address.
static constexpr size_t alignSize(size_t sizeBytes, size_t alignmentBytes)
_______________ Generic utilities _______________________________________________
T * resizeArray(T *&ptr, int32_t oldSize, int32_t newSize, T *newPtr=nullptr)
@ InProgress
construction started: temporary memory is reserved
@ NotConstructed
the object is not constructed
@ Constructed
the object is constructed, temporary memory is released
float length
length in material
float meanRho
mean density, g/cm^3
float meanX2X0
fraction of radiaton lenght
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"