138 const double* qPixels,
const double* qPad,
139 double* qPadPrediction,
int nPixels,
int nPads,
144 double* qRatio =
new double[nPads];
150 gsl_matrix_const_view Cij_gsl = gsl_matrix_const_view_array(Cij, nPixels, nPads);
151 gsl_vector_const_view qPixels_gsl = gsl_vector_const_view_array(qPixels, nPixels);
152 gsl_vector_view qPadPrediction_gsl = gsl_vector_view_array(qPadPrediction, nPads);
154 gsl_blas_dgemv(CblasTrans, 1.0, &Cij_gsl.matrix, &qPixels_gsl.vector, 0.0, &qPadPrediction_gsl.vector);
155 for (
int j = 0;
j < nPads;
j++) {
157 if (qPadPrediction[
j] < 1.0e-10) {
158 qPadPrediction[
j] = qPadPrediction[
j] + 1.0e-10;
160 qRatio[
j] = qPad[
j] / qPadPrediction[
j];
161 residu += fabs(qPadPrediction[
j] - qPad[
j]);
168 gsl_vector_view qRatio_gsl = gsl_vector_view_array(qRatio, nPads);
169 gsl_vector_view newQPixels_gsl = gsl_vector_view_array(newQPixels, nPixels);
171 gsl_blas_dgemv(CblasNoTrans, 1.0, &Cij_gsl.matrix, &qRatio_gsl.vector, 0.0, &newQPixels_gsl.vector);
173 for (
int i = 0;
i < nPixels;
i++) {
174 if (Ci[
i] > 1.0e-10) {
175 newQPixels[
i] = newQPixels[
i] * qPixels[
i] / Ci[
i];
181 for (
int i = 0;
i < nPixels;
i++) {
186 for (
int j = 0;
j < nPads;
j++) {
187 s_i = s_i + Cij[nPads *
i +
j] * qRatio[
j];
189 if (Ci[
i] > 1.0e-10) {
190 newQPixels[
i] = s_i * qPixels[
i] / Ci[
i];
196 for (
int i = 0;
i < nPixels;
i++) {
202 for (
int j = 0;
j < nPads;
j++) {
203 s_i = s_i + Cij[nPads *
i +
j] * qRatio[
j];
205 if (Ci[
i] > 1.0e-10) {
206 newQPixels[
i] = s_i * qPixels[
i] / Ci[
i];
263 const double* Cij,
Mask_t* maskCij,
264 int qCutMode,
double minPadError,
272 int nPixels =
pixels.getNbrOfPads();
274 const double*
x =
pixels.getX();
275 const double*
y =
pixels.getY();
276 const double* dx =
pixels.getDX();
277 const double* dy =
pixels.getDY();
278 double* qPixels =
new double[
pixels.getNbrOfPads()];
279 vectorCopy(
pixels.getCharges(),
pixels.getNbrOfPads(), qPixels);
284 vectorSetShort(maskCij, 1, nPads * nPixels);
287 double qPadPrediction[nPads];
288 double previousQPixels[nPixels];
291 bool converge =
false;
294 printf(
"Poisson EM\n");
296 " it. <Pixels_residu> <Pad_residu> max(Pad_residu) "
297 "sum(Pad_residu)/sum(qPad)\n");
299 double meanPixelsResidu = 0.0;
300 double maxPixelsResidu = 0.0;
302 double pixelVariation;
310 if (qCutMode == -1) {
322 for (
int i = 0;
i < (nPixels);
i++) {
323 if (qPixels[
i] < qPixCut) {
329 for (
int i = 0;
i < nPixels;
i++) {
352 vectorCopy(qPixels, nPixels, previousQPixels);
366 double pixResidu[nPixels];
367 vectorAddVector(previousQPixels, -1.0, qPixels, nPixels, pixResidu);
368 vectorAbs(pixResidu, nPixels, pixResidu);
370 pixelVariation = vectorSum(pixResidu, nPixels) / vectorSum(qPixels, nPixels);
371 int iMaxResidu = vectorArgMax(pixResidu, nPixels);
372 maxRelResidu = pixResidu[iMaxResidu] / previousQPixels[iMaxResidu];
376 double padResidu[nPads];
377 vectorAddVector(qPads, -1.0, qPadPrediction, nPads, padResidu);
378 double var = vectorDotProd(padResidu, padResidu, nPads) / nPads;
379 double E = vectorSum(qPads, nPads) / nPads;
380 padRelError = std::sqrt(var) / E;
383 printf(
" EM it=%d <pixelResidu>=%10.6f, dQPixel/qPixel=%10.6f, max(dQPix)/qPix=%10.6f, relPadError=%10.6f\n",
384 it, vectorSum(pixResidu, nPixels) / nPixels, pixelVariation, maxRelResidu, padRelError);
387 converge = (pixelVariation < minPadError * 0.03) && (padRelError < minPadError) ||
392 printf(
" Exit criterom pixelVariation=%d padRelError=%d itend=%d \n", (pixelVariation < minPadError * 0.03), (padRelError < minPadError), (it > nItMax));
396 int oldValueNPads =
pixels.getNbrOfPads();
397 pixels.setCharges(qPixels, nPixels);
400 k =
pixels.removePads(qPixCut);
408 printf(
" ??? Chi2 over NbrPads = (%f, %f); Chi2 over NbrObsPads = (%f, %f) \n",
409 chi.first, chi.second, chiObs.first, chiObs.second);
418 chi20 = chiObs.first;
419 chi21 = chiObs.second;
423 printf(
"End poisson EM :\n");
424 printf(
" Total Pad Charge = %14.6f\n", vectorSum(qPads, nPads));
425 printf(
" Total Predicted Charge = %14.6f\n",
426 vectorSum(qPadPrediction, nPads));
427 printf(
" Total Pixel Charge = %14.6f\n", vectorSum(qPixels, nPixels));
428 printf(
" EMPoisson qPixCut = %14.6f\n", qPixCut);
429 printf(
" Chi20 = %14.6f\n", chi20);
430 printf(
" Chi21 = %14.6f\n", chi21);
431 printf(
" # of iterations = %d\n", it);
432 printf(
" Max Pixel variation = %14.6f\n", maxPixelsResidu);
433 printf(
" Nbr of removed pixels = %d/%d\n", oldValueNPads - k,
437 return std::make_pair(chi20, chi21);
void fastIterateEMPoissonV0(const double *Cij, const double *Ci, const double *qPixels, const double *qPad, double *qPadPrediction, int nPixels, int nPads, double *newQPixels)
void fastIterateEMPoisson(const double *Cij, const double *Ci, const double *qPixels, const double *qPad, double *qPadPrediction, int nPixels, int nPads, double *newQPixels)
void iterateEMPoisson(const double *Cij, const double *Ci, const Mask_t *maskCij, const double *qPixels, const double *qPad, double *qPadPrediction, int nPixels, int nPads, double *newQPixels)
std::pair< double, double > PoissonEMLoop(const Pads &pads, Pads &pixels, const double *Cij, Mask_t *maskCij, int qCutMode, double minPadError, int nItMax)