@@ -148,9 +148,13 @@ void TPCFastSpaceChargeCorrectionHelper::fillSpaceChargeCorrectionFromMap(TPCFas
148148 if (!processingInverseCorrection) {
149149 info.resetMaxValues ();
150150 }
151+ info.updateMaxValues (1 ., 1 ., 1 .);
152+ info.updateMaxValues (-1 ., -1 ., -1 .);
153+
151154 if (nDataPoints >= 4 ) {
152155 std::vector<double > pointGU (nDataPoints);
153156 std::vector<double > pointGV (nDataPoints);
157+ std::vector<double > pointWeight (nDataPoints);
154158 std::vector<double > pointCorr (3 * nDataPoints); // 3 dimensions
155159 for (int i = 0 ; i < nDataPoints; ++i) {
156160 o2::gpu::TPCFastSpaceChargeCorrectionMap::CorrectionPoint p = data[i];
@@ -161,15 +165,14 @@ void TPCFastSpaceChargeCorrectionHelper::fillSpaceChargeCorrectionFromMap(TPCFas
161165 }
162166 pointGU[i] = gu;
163167 pointGV[i] = gv;
168+ pointWeight[i] = p.mWeight ;
164169 pointCorr[3 * i + 0 ] = p.mDx ;
165170 pointCorr[3 * i + 1 ] = p.mDy ;
166171 pointCorr[3 * i + 2 ] = p.mDz ;
167- if (!processingInverseCorrection) {
168- info.updateMaxValues (20 . * p.mDx , 20 . * p.mDy , 20 . * p.mDz );
169- }
172+ info.updateMaxValues (5 . * p.mDx , 5 . * p.mDy , 5 . * p.mDz );
170173 }
171- helper.approximateDataPoints (spline, splineParameters.data (), 0 ., spline.getGridX1 ().getUmax (), 0 ., spline.getGridX2 ().getUmax (), & pointGU[ 0 ] ,
172- & pointGV[ 0 ], & pointCorr[ 0 ] , nDataPoints);
174+ helper.approximateDataPoints (spline, splineParameters.data (), 0 ., spline.getGridX1 ().getUmax (), 0 ., spline.getGridX2 ().getUmax (), pointGU. data () ,
175+ pointGV. data (), pointCorr. data (), pointWeight. data () , nDataPoints);
173176 } else {
174177 for (int i = 0 ; i < spline.getNumberOfParameters (); i++) {
175178 splineParameters[i] = 0 .f ;
@@ -301,7 +304,7 @@ std::unique_ptr<TPCFastSpaceChargeCorrection> TPCFastSpaceChargeCorrectionHelper
301304 double dx, dy, dz;
302305 correctionLocal (iSector, iRow, y, z, dx, dy, dz);
303306 mCorrectionMap .addCorrectionPoint (iSector, iRow,
304- y, z, dx, dy, dz);
307+ y, z, dx, dy, dz, 1 . );
305308 }
306309 }
307310 } // row
@@ -593,14 +596,6 @@ std::unique_ptr<o2::gpu::TPCFastSpaceChargeCorrection> TPCFastSpaceChargeCorrect
593596 data.mCy *= -1 .;
594597 data.mCz *= -1 .;
595598 }
596- if (data.mNentries > 0 ) {
597- if (iSector < geo.getNumberOfSectorsA () && data.mZ < 0 ) {
598- LOG (error) << errMsg << " fitted Z coordinate " << data.mZ << " is negative for sector " << iSector;
599- }
600- if (iSector >= geo.getNumberOfSectorsA () && data.mZ > 0 ) {
601- LOG (error) << errMsg << " fitted Z coordinate " << data.mZ << " is positive for sector " << iSector;
602- }
603- }
604599 }
605600 };
606601 processor.Process (myThread);
@@ -624,6 +619,9 @@ std::unique_ptr<o2::gpu::TPCFastSpaceChargeCorrection> TPCFastSpaceChargeCorrect
624619 }
625620 }
626621
622+ double maxError[3 ] = {0 ., 0 ., 0 .};
623+ int nErrors = 0 ;
624+
627625 for (int iSector = 0 ; iSector < nSectors; iSector++) {
628626
629627 // now process the data row-by-row
@@ -682,9 +680,21 @@ std::unique_ptr<o2::gpu::TPCFastSpaceChargeCorrection> TPCFastSpaceChargeCorrect
682680 }
683681
684682 if (!msg.str ().empty ()) {
685- LOG (warning) << directionName << " correction: fitted voxel position is outside the voxel: "
686- << " sector " << iSector << " row " << iRow << " bin y " << iy << " bin z " << iz
687- << msg.str ();
683+ bool isMaxErrorExceeded = (fabs (data.mX - x) / dx > maxError[0 ]) ||
684+ (fabs (data.mY - vox.mY ) / vox.mDy > maxError[1 ]) ||
685+ (fabs (data.mZ - vox.mZ ) / vox.mDz > maxError[2 ]);
686+ static std::mutex mutex;
687+ mutex.lock ();
688+ nErrors++;
689+ if (nErrors < 20 || isMaxErrorExceeded) {
690+ LOG (warning) << directionName << " correction: error N " << nErrors << " fitted voxel position is outside the voxel: "
691+ << " sector " << iSector << " row " << iRow << " bin y " << iy << " bin z " << iz
692+ << msg.str ();
693+ maxError[0 ] = GPUCommonMath::Max (maxError[0 ], fabs (data.mX - x) / dx);
694+ maxError[1 ] = GPUCommonMath::Max (maxError[1 ], fabs (data.mY - vox.mY ) / vox.mDy );
695+ maxError[2 ] = GPUCommonMath::Max (maxError[2 ], fabs (data.mZ - vox.mZ ) / vox.mDz );
696+ }
697+ mutex.unlock ();
688698 }
689699
690700 } else { // no data, take voxel center position
@@ -773,17 +783,27 @@ std::unique_ptr<o2::gpu::TPCFastSpaceChargeCorrection> TPCFastSpaceChargeCorrect
773783 auto & info = correction.getSectorRowInfo (iSector, iRow);
774784 const auto & spline = correction.getSpline (iSector, iRow);
775785
776- auto addEdge = [&](int iy1, int iz1, int iy2, int iz2, int nSteps) {
786+ auto addVoxel = [&](int iy, int iz, double weight) {
787+ auto & vox = vRowVoxels[iy * nZ2Xbins + iz];
788+ if (vox.mSmoothingStep > 2 ) {
789+ LOG (fatal) << " empty voxel is not repared: y " << iy << " z " << iz;
790+ }
791+ auto & data = vSectorData[iSector * nRows + iRow][iy * nZ2Xbins + iz];
792+ map.addCorrectionPoint (iSector, iRow, data.mY , data.mZ , data.mCx , data.mCy , data.mCz , weight);
793+ };
794+
795+ auto addEdge = [&](int iy1, int iz1, int iy2, int iz2, int nPoints) {
796+ // add n points on the edge between two voxels excluding the voxel points
797+ if (nPoints < 1 )
798+ return ;
799+ if (iy1 < 0 || iy1 >= nY2Xbins || iz1 < 0 || iz1 >= nZ2Xbins)
800+ return ;
801+ if (iy2 < 0 || iy2 >= nY2Xbins || iz2 < 0 || iz2 >= nZ2Xbins)
802+ return ;
777803 auto & data1 = vSectorData[iSector * nRows + iRow][iy1 * nZ2Xbins + iz1];
778804 auto & vox1 = vRowVoxels[iy1 * nZ2Xbins + iz1];
779805 auto & data2 = vSectorData[iSector * nRows + iRow][iy2 * nZ2Xbins + iz2];
780806 auto & vox2 = vRowVoxels[iy2 * nZ2Xbins + iz2];
781- if (vox1.mSmoothingStep > 2 ) {
782- LOG (fatal) << " empty voxel is not repared: y " << iy1 << " z " << iz1;
783- }
784- if (vox2.mSmoothingStep > 2 ) {
785- LOG (fatal) << " empty voxel is not repared: y " << iy2 << " z " << iz2;
786- }
787807 double y1 = data1.mY ;
788808 double z1 = data1.mZ ;
789809 double cx1 = data1.mCx ;
@@ -795,32 +815,36 @@ std::unique_ptr<o2::gpu::TPCFastSpaceChargeCorrection> TPCFastSpaceChargeCorrect
795815 double cy2 = data2.mCy ;
796816 double cz2 = data2.mCz ;
797817
798- for (int is = 0 ; is < nSteps ; is++) {
799- double s2 = is / (double )nSteps ;
818+ for (int is = 1 ; is <= nPoints ; is++) {
819+ double s2 = is / (double )(nPoints + 1 ) ;
800820 double s1 = 1 . - s2;
801821 double y = s1 * y1 + s2 * y2;
802822 double z = s1 * z1 + s2 * z2;
803823 double cx = s1 * cx1 + s2 * cx2;
804824 double cy = s1 * cy1 + s2 * cy2;
805825 double cz = s1 * cz1 + s2 * cz2;
806- map.addCorrectionPoint (iSector, iRow, y, z, cx, cy, cz);
826+ map.addCorrectionPoint (iSector, iRow, y, z, cx, cy, cz, 1 . );
807827 }
808828 };
809829
830+ // original measurements weighted by 8 at each voxel and 8 additional artificial measurements around each voxel
831+ //
832+ // (y+1, z) 8 1 1 8 (y+1, z+1)
833+ // 1 1 1 1 1
834+ // 1 1 1 1 1
835+ // (y,z) 8 1 1 8 1
836+ // 1 1 1 1 1
837+
810838 for (int iy = 0 ; iy < nY2Xbins; iy++) {
811- for (int iz = 0 ; iz < nZ2Xbins - 1 ; iz++) {
812- addEdge (iy, iz, iy, iz + 1 , 3 );
839+ for (int iz = 0 ; iz < nZ2Xbins; iz++) {
840+ addVoxel (iy, iz, 8 );
841+ addEdge (iy, iz, iy, iz + 1 , 2 );
842+ addEdge (iy, iz, iy + 1 , iz, 2 );
843+ addEdge (iy, iz, iy + 1 , iz + 1 , 2 );
844+ addEdge (iy + 1 , iz, iy, iz + 1 , 2 );
813845 }
814- addEdge (iy, nZ2Xbins - 1 , iy, nZ2Xbins - 1 , 1 );
815846 }
816847
817- for (int iz = 0 ; iz < nZ2Xbins; iz++) {
818- for (int iy = 0 ; iy < nY2Xbins - 1 ; iy++) {
819- addEdge (iy, iz, iy + 1 , iz, 3 );
820- }
821- addEdge (nY2Xbins - 1 , iz, nY2Xbins - 1 , iz, 1 );
822- } // iy
823-
824848 } // iRow
825849 }; // myThread
826850
@@ -939,10 +963,11 @@ void TPCFastSpaceChargeCorrectionHelper::initInverse(std::vector<o2::gpu::TPCFas
939963 }
940964 }
941965
942- std::vector<double > dataPointGridU, dataPointGridV, dataPointF;
966+ std::vector<double > dataPointGridU, dataPointGridV, dataPointF, dataPointWeight ;
943967 dataPointGridU.reserve (gridU.size () * gridV.size ());
944968 dataPointGridV.reserve (gridU.size () * gridV.size ());
945969 dataPointF.reserve (3 * gridU.size () * gridV.size ());
970+ dataPointWeight.reserve (gridU.size () * gridV.size ());
946971
947972 for (int iu = 0 ; iu < gridU.size (); iu++) {
948973 for (int iv = 0 ; iv < gridV.size (); iv++) {
@@ -963,6 +988,7 @@ void TPCFastSpaceChargeCorrectionHelper::initInverse(std::vector<o2::gpu::TPCFas
963988 dataPointF.push_back (scale * dx);
964989 dataPointF.push_back (scale * dy);
965990 dataPointF.push_back (scale * dz);
991+ dataPointWeight.push_back (1 .);
966992 }
967993 }
968994
@@ -972,7 +998,7 @@ void TPCFastSpaceChargeCorrectionHelper::initInverse(std::vector<o2::gpu::TPCFas
972998 helper.approximateDataPoints (spline, splineParameters.data (), 0 ., spline.getGridX1 ().getUmax (),
973999 0 ., spline.getGridX2 ().getUmax (),
9741000 dataPointGridU.data (), dataPointGridV.data (),
975- dataPointF.data (), nDataPoints);
1001+ dataPointF.data (), dataPointWeight. data (), nDataPoints);
9761002
9771003 float * splineX = correction.getSplineDataInvX (sector, row);
9781004 float * splineUV = correction.getSplineDataInvYZ (sector, row);
0 commit comments