152static const double epsilon = 1e-10;
166static Succeeded find_start_values(
const shared_ptr<const ProjDataInfoCylindricalArcCorr> proj_data_info_sptr,
172 const float image_rad,
181 const float num_planes_per_axial_pos,
182 const float axial_pos_to_z_offset);
185check_values(
const shared_ptr<const ProjDataInfoCylindricalArcCorr> proj_data_info_sptr,
196 const float num_planes_per_axial_pos,
197 const float axial_pos_to_z_offset)
200 const double d_xy = proj_data_info_sptr->get_tangential_sampling();
202 const double R2 =
square(proj_data_info_sptr->get_ring_radius());
204 const double R2p = R2 / d_xy / d_xy;
206 const int num_planes_per_physical_ring = 2;
208 const double t = s + 0.5;
212 const double new_ds = X1 * cphi + Y1 * sphi - s;
213 const double root = sqrt(R2p - t * t);
215 const double z = (Z1 - num_planes_per_physical_ring * delta / 2 * ((-X1 * sphi + Y1 * cphi) / root + 1) - axial_pos_to_z_offset)
216 / num_planes_per_axial_pos;
217 const double new_dz = z - ring0;
219 if (fabs(ds - new_ds) > .005 || fabs(dz - new_dz) > .005)
221 warning(
"Difference ds (%g,%g) dz (%g,%g) at X=%d,Y=%d,Z=%d\n", ds, new_ds, dz, new_dz, X1, Y1, Z1);
236BackProjectorByBinUsingInterpolation::
237#if PIECEWISE_INTERPOLATION
238 piecewise_linear_interpolation_backproj3D_Cho_view_viewplus90
240 linear_interpolation_backproj3D_Cho_view_viewplus90
242 (Array<4, float>
const& Projptr,
243 VoxelsOnCartesianGrid<float>& image,
244 const shared_ptr<const ProjDataInfoCylindricalArcCorr> proj_data_info_sptr,
250 const int num_planes_per_axial_pos,
251 const float axial_pos_to_z_offset)
254#if PIECEWISE_INTERPOLATION
255 if (num_planes_per_axial_pos == 1 && delta != 0)
256 error(
"This version of the backprojector cannot be used for span>1. \
257Recompile %s with PIECEWISE_INTERPOLATION=0",
262 if (num_planes_per_axial_pos == 1 && delta != 0)
263 error(
"This version of the backprojector cannot be used for span>1. \
264Recompile %s with ALTERNATIVE not #defined",
271# error times sqrt(2)/iets met t
278 if (delta * proj_data_info_sptr_info_cyl_ptr->get_tangential_sampling() / proj_data_info_sptr_info_cyl_ptr->get_ring_radius()
281 error(
"This backprojector cannot handle such oblique segments: delta = %g. Sorry.\n", delta);
286 assert(cphi >= 0 - .001);
287 assert(sphi >= 0 - .001);
288 assert(cphi + sphi >= 1 - .001);
290 double dzvert, dzhor, ds;
291 double dsdiag, dzdiag, dz;
294 const float ring_unit = 1. / num_planes_per_axial_pos;
298 const int num_planes_per_physical_ring = 2;
299 assert(fabs(image.get_voxel_size().z() * num_planes_per_physical_ring / proj_data_info_sptr->get_ring_spacing() - 1) < 10E-4);
303 const float fovrad_in_mm = min((min(image.get_max_x(), -image.get_min_x())) * image.get_voxel_size().x(),
304 (min(image.get_max_y(), -image.get_min_y())) * image.get_voxel_size().y());
305 const float image_rad = fovrad_in_mm / image.get_voxel_size().x() - 2;
309 const int minplane = image.get_min_z();
310 const int maxplane = image.get_max_z();
312 if (find_start_values(proj_data_info_sptr,
319 image.get_voxel_size().z(),
327 num_planes_per_axial_pos,
328 axial_pos_to_z_offset)
361 const double K1A0 = Projptr[0][0][0][2] - Projptr[0][0][0][1];
362 const double K2A0 = Projptr[0][0][0][3] - Projptr[0][0][0][1];
363 const double K3A0 = Projptr[0][0][0][4] - Projptr[0][0][0][2] - K2A0;
364 const double K1A2 = Projptr[0][2][0][2] - Projptr[0][2][0][1];
365 const double K2A2 = Projptr[0][2][0][3] - Projptr[0][2][0][1];
366 const double K3A2 = Projptr[0][2][0][4] - Projptr[0][2][0][2] - K2A2;
368 const double K1A0n = Projptr[1][0][0][2] - Projptr[1][0][0][1];
369 const double K2A0n = Projptr[1][0][0][3] - Projptr[1][0][0][1];
370 const double K3A0n = Projptr[1][0][0][4] - Projptr[1][0][0][2] - K2A0n;
371 const double K1A2n = Projptr[1][2][0][2] - Projptr[1][2][0][1];
372 const double K2A2n = Projptr[1][2][0][3] - Projptr[1][2][0][1];
373 const double K3A2n = Projptr[1][2][0][4] - Projptr[1][2][0][2] - K2A2n;
375 const double K1P0 = Projptr[0][0][1][2] - Projptr[0][0][1][1];
376 const double K2P0 = Projptr[0][0][1][3] - Projptr[0][0][1][1];
377 const double K3P0 = Projptr[0][0][1][4] - Projptr[0][0][1][2] - K2P0;
378 const double K1P2 = Projptr[0][2][1][2] - Projptr[0][2][1][1];
379 const double K2P2 = Projptr[0][2][1][3] - Projptr[0][2][1][1];
380 const double K3P2 = Projptr[0][2][1][4] - Projptr[0][2][1][2] - K2P2;
382 const double K1P0n = Projptr[1][0][1][2] - Projptr[1][0][1][1];
383 const double K2P0n = Projptr[1][0][1][3] - Projptr[1][0][1][1];
384 const double K3P0n = Projptr[1][0][1][4] - Projptr[1][0][1][2] - K2P0n;
385 const double K1P2n = Projptr[1][2][1][2] - Projptr[1][2][1][1];
386 const double K2P2n = Projptr[1][2][1][3] - Projptr[1][2][1][1];
387 const double K3P2n = Projptr[1][2][1][4] - Projptr[1][2][1][2] - K2P2n;
389#if !PIECEWISE_INTERPOLATION
391 const double ZplusKorrA0 = ring_unit * K2A0;
392 const double ZplusKorrA2 = ring_unit * K2A2;
394 const double ZplusKorrA0n = ring_unit * K2A0n;
395 const double ZplusKorrA2n = ring_unit * K2A2n;
397 const double ZplusKorrP0 = ring_unit * K2P0;
398 const double ZplusKorrP2 = ring_unit * K2P2;
400 const double ZplusKorrP0n = ring_unit * K2P0n;
401 const double ZplusKorrP2n = ring_unit * K2P2n;
405 const double VA0 = dzvert * K2A0 + sphi * K1A0;
406 const double HA0 = dzhor * K2A0 - cphi * K1A0;
407 const double DA0 = VA0 + HA0;
408 const double VZA0 = VA0 + ring_unit * K2A0;
409 const double HZA0 = HA0 + ring_unit * K2A0;
410 const double DZA0 = DA0 + ring_unit * K2A0;
411 const double VA2 = dzvert * K2A2 + sphi * K1A2;
412 const double HA2 = dzhor * K2A2 - cphi * K1A2;
413 const double DA2 = VA2 + HA2;
414 const double VZA2 = VA2 + ring_unit * K2A2;
415 const double HZA2 = HA2 + ring_unit * K2A2;
416 const double DZA2 = DA2 + ring_unit * K2A2;
418 const double VA0n = dzvert * K2A0n + sphi * K1A0n;
419 const double HA0n = dzhor * K2A0n - cphi * K1A0n;
420 const double DA0n = VA0n + HA0n;
421 const double VZA0n = VA0n + ring_unit * K2A0n;
422 const double HZA0n = HA0n + ring_unit * K2A0n;
423 const double DZA0n = DA0n + ring_unit * K2A0n;
424 const double VA2n = dzvert * K2A2n + sphi * K1A2n;
425 const double HA2n = dzhor * K2A2n - cphi * K1A2n;
426 const double DA2n = VA2n + HA2n;
427 const double VZA2n = VA2n + ring_unit * K2A2n;
428 const double HZA2n = HA2n + ring_unit * K2A2n;
429 const double DZA2n = DA2n + ring_unit * K2A2n;
431 const double VP0 = dzvert * K2P0 + sphi * K1P0;
432 const double HP0 = dzhor * K2P0 - cphi * K1P0;
433 const double DP0 = VP0 + HP0;
434 const double VZP0 = VP0 + ring_unit * K2P0;
435 const double HZP0 = HP0 + ring_unit * K2P0;
436 const double DZP0 = DP0 + ring_unit * K2P0;
437 const double VP2 = dzvert * K2P2 + sphi * K1P2;
438 const double HP2 = dzhor * K2P2 - cphi * K1P2;
439 const double DP2 = VP2 + HP2;
440 const double VZP2 = VP2 + ring_unit * K2P2;
441 const double HZP2 = HP2 + ring_unit * K2P2;
442 const double DZP2 = DP2 + ring_unit * K2P2;
444 const double VP0n = dzvert * K2P0n + sphi * K1P0n;
445 const double HP0n = dzhor * K2P0n - cphi * K1P0n;
446 const double DP0n = VP0n + HP0n;
447 const double VZP0n = VP0n + ring_unit * K2P0n;
448 const double HZP0n = HP0n + ring_unit * K2P0n;
449 const double DZP0n = DP0n + ring_unit * K2P0n;
450 const double VP2n = dzvert * K2P2n + sphi * K1P2n;
451 const double HP2n = dzhor * K2P2n - cphi * K1P2n;
452 const double DP2n = VP2n + HP2n;
453 const double VZP2n = VP2n + ring_unit * K2P2n;
454 const double HZP2n = HP2n + ring_unit * K2P2n;
455 const double DZP2n = DP2n + ring_unit * K2P2n;
459 double UpA0 = Projptr[0][0][0][1] + ds * K1A0 + dz * K2A0;
460 double UpA2 = Projptr[0][2][0][1] + ds * K1A2 + dz * K2A2;
462 double UpA0n = Projptr[1][0][0][1] + ds * K1A0n + dz * K2A0n;
463 double UpA2n = Projptr[1][2][0][1] + ds * K1A2n + dz * K2A2n;
465 double UpP0 = Projptr[0][0][1][1] + ds * K1P0 + dz * K2P0;
466 double UpP2 = Projptr[0][2][1][1] + ds * K1P2 + dz * K2P2;
468 double UpP0n = Projptr[1][0][1][1] + ds * K1P0n + dz * K2P0n;
469 double UpP2n = Projptr[1][2][1][1] + ds * K1P2n + dz * K2P2n;
473 const double ZplusKorrA0 = K2A0;
474 const double ZplusKorrA2 = K2A2;
476 const double ZplusKorrA0n = K2A0n;
477 const double ZplusKorrA2n = K2A2n;
479 const double ZplusKorrP0 = K2P0;
480 const double ZplusKorrP2 = K2P2;
482 const double ZplusKorrP0n = K2P0n;
483 const double ZplusKorrP2n = K2P2n;
487 const double VA0a0 = +sphi * K1A0;
488 const double HA0a0 = -cphi * K1A0;
489 const double DA0a0 = VA0a0 + HA0a0;
490 const double VA2a0 = +sphi * K1A2;
491 const double HA2a0 = -cphi * K1A2;
492 const double DA2a0 = VA2a0 + HA2a0;
494 const double VA0na0 = +sphi * K1A0n;
495 const double HA0na0 = -cphi * K1A0n;
496 const double DA0na0 = VA0na0 + HA0na0;
497 const double VA2na0 = +sphi * K1A2n;
498 const double HA2na0 = -cphi * K1A2n;
499 const double DA2na0 = VA2na0 + HA2na0;
501 const double VP0a0 = +sphi * K1P0;
502 const double HP0a0 = -cphi * K1P0;
503 const double DP0a0 = VP0a0 + HP0a0;
504 const double VP2a0 = +sphi * K1P2;
505 const double HP2a0 = -cphi * K1P2;
506 const double DP2a0 = VP2a0 + HP2a0;
508 const double VP0na0 = +sphi * K1P0n;
509 const double HP0na0 = -cphi * K1P0n;
510 const double DP0na0 = VP0na0 + HP0na0;
511 const double VP2na0 = +sphi * K1P2n;
512 const double HP2na0 = -cphi * K1P2n;
513 const double DP2na0 = VP2na0 + HP2na0;
515 const double VA0a1 = +sphi * (K1A0 + K3A0);
516 const double HA0a1 = -cphi * (K1A0 + K3A0);
517 const double DA0a1 = VA0a1 + HA0a1;
518 const double VA2a1 = +sphi * (K1A2 + K3A2);
519 const double HA2a1 = -cphi * (K1A2 + K3A2);
520 const double DA2a1 = VA2a1 + HA2a1;
522 const double VA0na1 = +sphi * (K1A0n + K3A0n);
523 const double HA0na1 = -cphi * (K1A0n + K3A0n);
524 const double DA0na1 = VA0na1 + HA0na1;
525 const double VA2na1 = +sphi * (K1A2n + K3A2n);
526 const double HA2na1 = -cphi * (K1A2n + K3A2n);
527 const double DA2na1 = VA2na1 + HA2na1;
529 const double VP0a1 = +sphi * (K1P0 + K3P0);
530 const double HP0a1 = -cphi * (K1P0 + K3P0);
531 const double DP0a1 = VP0a1 + HP0a1;
532 const double VP2a1 = +sphi * (K1P2 + K3P2);
533 const double HP2a1 = -cphi * (K1P2 + K3P2);
534 const double DP2a1 = VP2a1 + HP2a1;
536 const double VP0na1 = +sphi * (K1P0n + K3P0n);
537 const double HP0na1 = -cphi * (K1P0n + K3P0n);
538 const double DP0na1 = VP0na1 + HP0na1;
539 const double VP2na1 = +sphi * (K1P2n + K3P2n);
540 const double HP2na1 = -cphi * (K1P2n + K3P2n);
541 const double DP2na1 = VP2na1 + HP2na1;
543 const double VA0 = VA0a0 * 1.5 - VA0a1 / 2 + 2 * dzvert * K2A0;
544 const double HA0 = HA0a0 * 1.5 - HA0a1 / 2 + 2 * dzhor * K2A0;
545 const double DA0 = VA0 + HA0;
546 const double VZA0 = VA0 + K2A0;
547 const double HZA0 = HA0 + K2A0;
548 const double DZA0 = DA0 + K2A0;
549 const double VA2 = VA2a0 * 1.5 - VA2a1 / 2 + 2 * dzvert * K2A2;
550 const double HA2 = HA2a0 * 1.5 - HA2a1 / 2 + 2 * dzhor * K2A2;
551 const double DA2 = VA2 + HA2;
552 const double VZA2 = VA2 + K2A2;
553 const double HZA2 = HA2 + K2A2;
554 const double DZA2 = DA2 + K2A2;
556 const double VA0n = VA0na0 * 1.5 - VA0na1 / 2 + 2 * dzvert * K2A0n;
557 const double HA0n = HA0na0 * 1.5 - HA0na1 / 2 + 2 * dzhor * K2A0n;
558 const double DA0n = VA0n + HA0n;
559 const double VZA0n = VA0n + K2A0n;
560 const double HZA0n = HA0n + K2A0n;
561 const double DZA0n = DA0n + K2A0n;
562 const double VA2n = VA2na0 * 1.5 - VA2na1 / 2 + 2 * dzvert * K2A2n;
563 const double HA2n = HA2na0 * 1.5 - HA2na1 / 2 + 2 * dzhor * K2A2n;
564 const double DA2n = VA2n + HA2n;
565 const double VZA2n = VA2n + K2A2n;
566 const double HZA2n = HA2n + K2A2n;
567 const double DZA2n = DA2n + K2A2n;
569 const double VP0 = VP0a0 * 1.5 - VP0a1 / 2 + 2 * dzvert * K2P0;
570 const double HP0 = HP0a0 * 1.5 - HP0a1 / 2 + 2 * dzhor * K2P0;
571 const double DP0 = VP0 + HP0;
572 const double VZP0 = VP0 + K2P0;
573 const double HZP0 = HP0 + K2P0;
574 const double DZP0 = DP0 + K2P0;
575 const double VP2 = VP2a0 * 1.5 - VP2a1 / 2 + 2 * dzvert * K2P2;
576 const double HP2 = HP2a0 * 1.5 - HP2a1 / 2 + 2 * dzhor * K2P2;
577 const double DP2 = VP2 + HP2;
578 const double VZP2 = VP2 + K2P2;
579 const double HZP2 = HP2 + K2P2;
580 const double DZP2 = DP2 + K2P2;
582 const double VP0n = VP0na0 * 1.5 - VP0na1 / 2 + 2 * dzvert * K2P0n;
583 const double HP0n = HP0na0 * 1.5 - HP0na1 / 2 + 2 * dzhor * K2P0n;
584 const double DP0n = VP0n + HP0n;
585 const double VZP0n = VP0n + K2P0n;
586 const double HZP0n = HP0n + K2P0n;
587 const double DZP0n = DP0n + K2P0n;
588 const double VP2n = VP2na0 * 1.5 - VP2na1 / 2 + 2 * dzvert * K2P2n;
589 const double HP2n = HP2na0 * 1.5 - HP2na1 / 2 + 2 * dzhor * K2P2n;
590 const double DP2n = VP2n + HP2n;
591 const double VZP2n = VP2n + K2P2n;
592 const double HZP2n = HP2n + K2P2n;
593 const double DZP2n = DP2n + K2P2n;
596 double A0a0 = Projptr[0][0][0][1] + ds * K1A0;
597 double A0a1 = Projptr[0][0][0][3] + ds * (K1A0 + K3A0);
598 double A2a0 = Projptr[0][2][0][1] + ds * K1A2;
599 double A2a1 = Projptr[0][2][0][3] + ds * (K1A2 + K3A2);
601 double P0na0 = Projptr[1][0][1][1] + ds * K1P0n;
602 double P0na1 = Projptr[1][0][1][3] + ds * (K1P0n + K3P0n);
603 double P2na0 = Projptr[1][2][1][1] + ds * K1P2n;
604 double P2na1 = Projptr[1][2][1][3] + ds * (K1P2n + K3P2n);
606 double A0na0 = Projptr[1][0][0][1] + ds * K1A0n;
607 double A0na1 = Projptr[1][0][0][3] + ds * (K1A0n + K3A0n);
608 double A2na0 = Projptr[1][2][0][1] + ds * K1A2n;
609 double A2na1 = Projptr[1][2][0][3] + ds * (K1A2n + K3A2n);
611 double P0a0 = Projptr[0][0][1][1] + ds * K1P0;
612 double P0a1 = Projptr[0][0][1][3] + ds * (K1P0 + K3P0);
613 double P2a0 = Projptr[0][2][1][1] + ds * K1P2;
614 double P2a1 = Projptr[0][2][1][3] + ds * (K1P2 + K3P2);
616 double UpA0 = 2 * (Projptr[0][0][0][1] + ds * K1A0 + dz * K2A0) - (A0a0 + A0a1) / 2;
617 double UpA2 = 2 * (Projptr[0][2][0][1] + ds * K1A2 + dz * K2A2) - (A2a0 + A2a1) / 2;
619 double UpA0n = 2 * (Projptr[1][0][0][1] + ds * K1A0n + dz * K2A0n) - (A0na0 + A0na1) / 2;
620 double UpA2n = 2 * (Projptr[1][2][0][1] + ds * K1A2n + dz * K2A2n) - (A2na0 + A2na1) / 2;
622 double UpP0 = 2 * (Projptr[0][0][1][1] + ds * K1P0 + dz * K2P0) - (P0a0 + P0a1) / 2;
623 double UpP2 = 2 * (Projptr[0][2][1][1] + ds * K1P2 + dz * K2P2) - (P2a0 + P2a1) / 2;
625 double UpP0n = 2 * (Projptr[1][0][1][1] + ds * K1P0n + dz * K2P0n) - (P0na0 + P0na1) / 2;
626 double UpP2n = 2 * (Projptr[1][2][1][1] + ds * K1P2n + dz * K2P2n) - (P2na0 + P2na1) / 2;
640 = (2 * num_planes_per_axial_pos * (ring0 + 0.5) + num_planes_per_physical_ring * delta + 2 * axial_pos_to_z_offset - Z);
642 Q = (int)floor(Qf + 0.5);
643 assert(fabs(Q - Qf) < 10E-4);
646 dzdiag = dzvert + dzhor;
647 dsdiag = -cphi + sphi;
665 assert(dz <= ring_unit + epsilon);
670 const int Zplus = Z + 1;
671 const int Qmin = Q - 1;
673#if PIECEWISE_INTERPOLATION
677 const bool do_s_symmetry = (s != 0 || fabs(ds) > epsilon);
678 const double twodsdz = 2 * ds * dz;
679 const double twodsdz2 = 2 * ds * (dz + 0.5);
681 if (Z >= minplane && Z <= maxplane)
684 image[Z][Y][X] += (dz <= 0.25) ? A0a0 : UpA0 + twodsdz * K3A0;
685 image[Z][X][-Y] += (dz <= 0.25) ? A2a0 : UpA2 + twodsdz * K3A2;
688 image[Z][-Y][-X] += (dz <= 0.25) ? P0na0 : UpP0n + twodsdz * K3P0n;
689 image[Z][-X][Y] += (dz <= 0.25) ? P2na0 : UpP2n + twodsdz * K3P2n;
692 if (Zplus >= minplane && Zplus <= maxplane)
694 image[Zplus][Y][X] += (dz >= 0.25) ? A0a1 : UpA0 + twodsdz2 * K3A0 + ZplusKorrA0;
695 image[Zplus][X][-Y] += (dz >= 0.25) ? A2a1 : UpA2 + twodsdz2 * K3A2 + ZplusKorrA2;
698 image[Zplus][-Y][-X] += (dz >= 0.25) ? P0na1 : UpP0n + twodsdz2 * K3P0n + ZplusKorrP0n;
699 image[Zplus][-X][Y] += (dz >= 0.25) ? P2na1 : UpP2n + twodsdz2 * K3P2n + ZplusKorrP2n;
702 if (Q >= minplane && Q <= maxplane)
704 image[Q][Y][X] += (dz <= 0.25) ? A0na0 : UpA0n + twodsdz * K3A0n;
705 image[Q][X][-Y] += (dz <= 0.25) ? A2na0 : UpA2n + twodsdz * K3A2n;
708 image[Q][-Y][-X] += (dz <= 0.25) ? P0a0 : UpP0 + twodsdz * K3P0;
709 image[Q][-X][Y] += (dz <= 0.25) ? P2a0 : UpP2 + twodsdz * K3P2;
712 if (Qmin >= minplane && Qmin <= maxplane)
714 image[Qmin][Y][X] += (dz >= 0.25) ? A0na1 : UpA0n + twodsdz2 * K3A0n + ZplusKorrA0n;
715 image[Qmin][X][-Y] += (dz >= 0.25) ? A2na1 : UpA2n + twodsdz2 * K3A2n + ZplusKorrA2n;
718 image[Qmin][-Y][-X] += (dz >= 0.25) ? P0a1 : UpP0 + twodsdz2 * K3P0 + ZplusKorrP0;
719 image[Qmin][-X][Y] += (dz >= 0.25) ? P2a1 : UpP2 + twodsdz2 * K3P2 + ZplusKorrP2;
728 const bool do_s_symmetry = (s != 0 || fabs(ds) > epsilon);
729 const double dsdz = ds * dz;
730 const double dsdz2 = ds * (dz + ring_unit);
732 if (Z >= minplane && Z <= maxplane)
734 image[Z][Y][X] += UpA0 + dsdz * K3A0;
735 image[Z][X][-Y] += UpA2 + dsdz * K3A2;
738 image[Z][-Y][-X] += UpP0n + dsdz * K3P0n;
739 image[Z][-X][Y] += UpP2n + dsdz * K3P2n;
744 if (Zplus >= minplane && Zplus <= maxplane && ring_unit == 0.5)
746 image[Zplus][Y][X] += UpA0 + dsdz2 * K3A0 + ZplusKorrA0;
747 image[Zplus][X][-Y] += UpA2 + dsdz2 * K3A2 + ZplusKorrA2;
750 image[Zplus][-Y][-X] += UpP0n + dsdz2 * K3P0n + ZplusKorrP0n;
751 image[Zplus][-X][Y] += UpP2n + dsdz2 * K3P2n + ZplusKorrP2n;
754 if (Q >= minplane && Q <= maxplane)
756 image[Q][Y][X] += UpA0n + dsdz * K3A0n;
757 image[Q][X][-Y] += UpA2n + dsdz * K3A2n;
760 image[Q][-Y][-X] += UpP0 + dsdz * K3P0;
761 image[Q][-X][Y] += UpP2 + dsdz * K3P2;
766 if (Qmin >= minplane && Qmin <= maxplane && ring_unit == 0.5)
768 image[Qmin][Y][X] += UpA0n + dsdz2 * K3A0n + ZplusKorrA0n;
769 image[Qmin][X][-Y] += UpA2n + dsdz2 * K3A2n + ZplusKorrA2n;
772 image[Qmin][-Y][-X] += UpP0 + dsdz2 * K3P0 + ZplusKorrP0;
773 image[Qmin][-X][Y] += UpP2 + dsdz2 * K3P2 + ZplusKorrP2;
783 TMP2 = UpA0 + dz * TMP1;
784 if (Z >= minplane && Z <= maxplane)
785 image[Z][Y][X] += TMP2;
788 if (Zplus >= minplane && Zplus <= maxplane && ring_unit == 0.5)
789 image[Zplus][Y][X] += TMP2 + ring_unit * TMP1 + ZplusKorrA0;
791 TMP2 = UpA2 + dz * TMP1;
792 if (Z >= minplane && Z <= maxplane)
793 image[Z][X][-Y] += TMP2;
796 if (Zplus >= minplane && Zplus <= maxplane && ring_unit == 0.5)
797 image[Zplus][X][-Y] += TMP2 + ring_unit * TMP1 + ZplusKorrA2;
800 TMP2 = UpA0n + dz * TMP1;
801 if (Q >= minplane && Q <= maxplane)
802 image[Q][Y][X] += TMP2;
805 if (Qmin >= minplane && Qmin <= maxplane && ring_unit == 0.5)
806 image[Qmin][Y][X] += TMP2 + ring_unit * TMP1 + ZplusKorrA0n;
808 TMP2 = UpA2n + dz * TMP1;
809 if (Q >= minplane && Q <= maxplane)
810 image[Q][X][-Y] += TMP2;
813 if (Qmin >= minplane && Qmin <= maxplane && ring_unit == 0.5)
814 image[Qmin][X][-Y] += TMP2 + ring_unit * TMP1 + ZplusKorrA2n;
818 if (s != 0 || fabs(ds) > epsilon)
821 TMP2 = UpP0 + dz * TMP1;
822 if (Q >= minplane && Q <= maxplane)
823 image[Q][-Y][-X] += TMP2;
826 if (Qmin >= minplane && Qmin <= maxplane && ring_unit == 0.5)
827 image[Qmin][-Y][-X] += TMP2 + ring_unit * TMP1 + ZplusKorrP0;
829 TMP2 = UpP2 + dz * TMP1;
830 if (Q >= minplane && Q <= maxplane)
831 image[Q][-X][Y] += TMP2;
834 if (Qmin >= minplane && Qmin <= maxplane && ring_unit == 0.5)
835 image[Qmin][-X][Y] += TMP2 + ring_unit * TMP1 + ZplusKorrP2;
838 TMP2 = UpP0n + dz * TMP1;
839 if (Z >= minplane && Z <= maxplane)
840 image[Z][-Y][-X] += TMP2;
843 if (Zplus >= minplane && Zplus <= maxplane && ring_unit == 0.5)
844 image[Zplus][-Y][-X] += TMP2 + ring_unit * TMP1 + ZplusKorrP0n;
846 TMP2 = UpP2n + dz * TMP1;
847 if (Z >= minplane && Z <= maxplane)
848 image[Z][-X][Y] += TMP2;
851 if (Zplus >= minplane && Zplus <= maxplane && ring_unit == 0.5)
852 image[Zplus][-X][Y] += TMP2 + ring_unit * TMP1 + ZplusKorrP2n;
886 UpA0n += HZA0n - HA0n;
887 UpA2n += HZA2n - HA2n;
890 UpP0n += HZP0n - HP0n;
891 UpP2n += HZP2n - HP2n;
907#if PIECEWISE_INTERPOLATION
928 else if (ds < 1 - sphi)
956 UpA0n += VZA0n - VA0n;
957 UpA2n += VZA2n - VA2n;
960 UpP0n += VZP0n - VP0n;
961 UpP2n += VZP2n - VP2n;
976#if PIECEWISE_INTERPOLATION
1017 while (dz < epsilon)
1024 UpA0n += DZA0n - DA0n;
1025 UpA2n += DZA2n - DA2n;
1028 UpP0n += DZP0n - DP0n;
1029 UpP2n += DZP2n - DP2n;
1045#if PIECEWISE_INTERPOLATION
1066 proj_data_info_sptr, delta, cphi, sphi, s, ring0, X, Y, Z, ds, dz, num_planes_per_axial_pos, axial_pos_to_z_offset);
1067 }
while ((X * X + Y * Y <= image_rad * image_rad) && (Z <= maxplane || Q >= minplane));
1083BackProjectorByBinUsingInterpolation::
1084#if PIECEWISE_INTERPOLATION
1085 piecewise_linear_interpolation_backproj3D_Cho_view_viewplus90_180minview_90minview
1087 linear_interpolation_backproj3D_Cho_view_viewplus90_180minview_90minview
1089 (Array<4, float>
const& Projptr,
1090 VoxelsOnCartesianGrid<float>& image,
1091 const shared_ptr<const ProjDataInfoCylindricalArcCorr> proj_data_info_sptr,
1097 const int num_planes_per_axial_pos,
1098 const float axial_pos_to_z_offset)
1101#if PIECEWISE_INTERPOLATION
1102 if (num_planes_per_axial_pos == 1 && delta != 0)
1103 error(
"This version of the backprojector cannot be used for span>1. \
1104Recompile %s with PIECEWISE_INTERPOLATION=0",
1109 if (num_planes_per_axial_pos == 1 && delta != 0)
1110 error(
"This version of the backprojector cannot be used for span>1. \
1111Recompile %s with ALTERNATIVE not #defined",
1124 if (delta * proj_data_info_sptr_info_cyl_ptr->get_tangential_sampling() / proj_data_info_sptr_info_cyl_ptr->get_ring_radius()
1127 error(
"This backprojector cannot handle such oblique segments: delta = %g. Sorry.\n", delta);
1132 assert(cphi >= 0 - .001);
1133 assert(sphi >= 0 - .001);
1134 assert(cphi + sphi >= 1 - .001);
1136 const float ring_unit = 1. / num_planes_per_axial_pos;
1139 const int num_planes_per_physical_ring = 2;
1140 assert(fabs(image.get_voxel_size().z() * num_planes_per_physical_ring / proj_data_info_sptr->get_ring_spacing() - 1) < 10E-4);
1142 double dzvert, dzhor, ds;
1143 double dsdiag, dzdiag, dz;
1148 const float fovrad_in_mm = min((min(image.get_max_x(), -image.get_min_x())) * image.get_voxel_size().x(),
1149 (min(image.get_max_y(), -image.get_min_y())) * image.get_voxel_size().y());
1150 const float image_rad = fovrad_in_mm / image.get_voxel_size().x() - 2;
1153 const int minplane = image.get_min_z();
1154 const int maxplane = image.get_max_z();
1156 if (find_start_values(proj_data_info_sptr,
1163 image.get_voxel_size().z(),
1171 num_planes_per_axial_pos,
1172 axial_pos_to_z_offset)
1181 const double K1A0 = Projptr[0][0][0][2] - Projptr[0][0][0][1];
1182 const double K2A0 = Projptr[0][0][0][3] - Projptr[0][0][0][1];
1183 const double K3A0 = Projptr[0][0][0][4] - Projptr[0][0][0][2] - K2A0;
1184 const double K1A1 = Projptr[0][1][0][2] - Projptr[0][1][0][1];
1185 const double K2A1 = Projptr[0][1][0][3] - Projptr[0][1][0][1];
1186 const double K3A1 = Projptr[0][1][0][4] - Projptr[0][1][0][2] - K2A1;
1187 const double K1A2 = Projptr[0][2][0][2] - Projptr[0][2][0][1];
1188 const double K2A2 = Projptr[0][2][0][3] - Projptr[0][2][0][1];
1189 const double K3A2 = Projptr[0][2][0][4] - Projptr[0][2][0][2] - K2A2;
1190 const double K1A3 = Projptr[0][3][0][2] - Projptr[0][3][0][1];
1191 const double K2A3 = Projptr[0][3][0][3] - Projptr[0][3][0][1];
1192 const double K3A3 = Projptr[0][3][0][4] - Projptr[0][3][0][2] - K2A3;
1194 const double K1A0n = Projptr[1][0][0][2] - Projptr[1][0][0][1];
1195 const double K2A0n = Projptr[1][0][0][3] - Projptr[1][0][0][1];
1196 const double K3A0n = Projptr[1][0][0][4] - Projptr[1][0][0][2] - K2A0n;
1197 const double K1A1n = Projptr[1][1][0][2] - Projptr[1][1][0][1];
1198 const double K2A1n = Projptr[1][1][0][3] - Projptr[1][1][0][1];
1199 const double K3A1n = Projptr[1][1][0][4] - Projptr[1][1][0][2] - K2A1n;
1200 const double K1A2n = Projptr[1][2][0][2] - Projptr[1][2][0][1];
1201 const double K2A2n = Projptr[1][2][0][3] - Projptr[1][2][0][1];
1202 const double K3A2n = Projptr[1][2][0][4] - Projptr[1][2][0][2] - K2A2n;
1203 const double K1A3n = Projptr[1][3][0][2] - Projptr[1][3][0][1];
1204 const double K2A3n = Projptr[1][3][0][3] - Projptr[1][3][0][1];
1205 const double K3A3n = Projptr[1][3][0][4] - Projptr[1][3][0][2] - K2A3n;
1207 const double K1P0 = Projptr[0][0][1][2] - Projptr[0][0][1][1];
1208 const double K2P0 = Projptr[0][0][1][3] - Projptr[0][0][1][1];
1209 const double K3P0 = Projptr[0][0][1][4] - Projptr[0][0][1][2] - K2P0;
1210 const double K1P1 = Projptr[0][1][1][2] - Projptr[0][1][1][1];
1211 const double K2P1 = Projptr[0][1][1][3] - Projptr[0][1][1][1];
1212 const double K3P1 = Projptr[0][1][1][4] - Projptr[0][1][1][2] - K2P1;
1213 const double K1P2 = Projptr[0][2][1][2] - Projptr[0][2][1][1];
1214 const double K2P2 = Projptr[0][2][1][3] - Projptr[0][2][1][1];
1215 const double K3P2 = Projptr[0][2][1][4] - Projptr[0][2][1][2] - K2P2;
1216 const double K1P3 = Projptr[0][3][1][2] - Projptr[0][3][1][1];
1217 const double K2P3 = Projptr[0][3][1][3] - Projptr[0][3][1][1];
1218 const double K3P3 = Projptr[0][3][1][4] - Projptr[0][3][1][2] - K2P3;
1220 const double K1P0n = Projptr[1][0][1][2] - Projptr[1][0][1][1];
1221 const double K2P0n = Projptr[1][0][1][3] - Projptr[1][0][1][1];
1222 const double K3P0n = Projptr[1][0][1][4] - Projptr[1][0][1][2] - K2P0n;
1223 const double K1P1n = Projptr[1][1][1][2] - Projptr[1][1][1][1];
1224 const double K2P1n = Projptr[1][1][1][3] - Projptr[1][1][1][1];
1225 const double K3P1n = Projptr[1][1][1][4] - Projptr[1][1][1][2] - K2P1n;
1226 const double K1P2n = Projptr[1][2][1][2] - Projptr[1][2][1][1];
1227 const double K2P2n = Projptr[1][2][1][3] - Projptr[1][2][1][1];
1228 const double K3P2n = Projptr[1][2][1][4] - Projptr[1][2][1][2] - K2P2n;
1229 const double K1P3n = Projptr[1][3][1][2] - Projptr[1][3][1][1];
1230 const double K2P3n = Projptr[1][3][1][3] - Projptr[1][3][1][1];
1231 const double K3P3n = Projptr[1][3][1][4] - Projptr[1][3][1][2] - K2P3n;
1233#if !PIECEWISE_INTERPOLATION
1235 const double ZplusKorrA0 = ring_unit * K2A0;
1236 const double ZplusKorrA1 = ring_unit * K2A1;
1237 const double ZplusKorrA2 = ring_unit * K2A2;
1238 const double ZplusKorrA3 = ring_unit * K2A3;
1240 const double ZplusKorrA0n = ring_unit * K2A0n;
1241 const double ZplusKorrA1n = ring_unit * K2A1n;
1242 const double ZplusKorrA2n = ring_unit * K2A2n;
1243 const double ZplusKorrA3n = ring_unit * K2A3n;
1245 const double ZplusKorrP0 = ring_unit * K2P0;
1246 const double ZplusKorrP1 = ring_unit * K2P1;
1247 const double ZplusKorrP2 = ring_unit * K2P2;
1248 const double ZplusKorrP3 = ring_unit * K2P3;
1250 const double ZplusKorrP0n = ring_unit * K2P0n;
1251 const double ZplusKorrP1n = ring_unit * K2P1n;
1252 const double ZplusKorrP2n = ring_unit * K2P2n;
1253 const double ZplusKorrP3n = ring_unit * K2P3n;
1257 const double VA0 = dzvert * K2A0 + sphi * K1A0;
1258 const double HA0 = dzhor * K2A0 - cphi * K1A0;
1259 const double DA0 = VA0 + HA0;
1260 const double VZA0 = VA0 + ring_unit * K2A0;
1261 const double HZA0 = HA0 + ring_unit * K2A0;
1262 const double DZA0 = DA0 + ring_unit * K2A0;
1263 const double VA1 = dzvert * K2A1 + sphi * K1A1;
1264 const double HA1 = dzhor * K2A1 - cphi * K1A1;
1265 const double DA1 = VA1 + HA1;
1266 const double VZA1 = VA1 + ring_unit * K2A1;
1267 const double HZA1 = HA1 + ring_unit * K2A1;
1268 const double DZA1 = DA1 + ring_unit * K2A1;
1269 const double VA2 = dzvert * K2A2 + sphi * K1A2;
1270 const double HA2 = dzhor * K2A2 - cphi * K1A2;
1271 const double DA2 = VA2 + HA2;
1272 const double VZA2 = VA2 + ring_unit * K2A2;
1273 const double HZA2 = HA2 + ring_unit * K2A2;
1274 const double DZA2 = DA2 + ring_unit * K2A2;
1275 const double VA3 = dzvert * K2A3 + sphi * K1A3;
1276 const double HA3 = dzhor * K2A3 - cphi * K1A3;
1277 const double DA3 = VA3 + HA3;
1278 const double VZA3 = VA3 + ring_unit * K2A3;
1279 const double HZA3 = HA3 + ring_unit * K2A3;
1280 const double DZA3 = DA3 + ring_unit * K2A3;
1282 const double VA0n = dzvert * K2A0n + sphi * K1A0n;
1283 const double HA0n = dzhor * K2A0n - cphi * K1A0n;
1284 const double DA0n = VA0n + HA0n;
1285 const double VZA0n = VA0n + ring_unit * K2A0n;
1286 const double HZA0n = HA0n + ring_unit * K2A0n;
1287 const double DZA0n = DA0n + ring_unit * K2A0n;
1288 const double VA1n = dzvert * K2A1n + sphi * K1A1n;
1289 const double HA1n = dzhor * K2A1n - cphi * K1A1n;
1290 const double DA1n = VA1n + HA1n;
1291 const double VZA1n = VA1n + ring_unit * K2A1n;
1292 const double HZA1n = HA1n + ring_unit * K2A1n;
1293 const double DZA1n = DA1n + ring_unit * K2A1n;
1294 const double VA2n = dzvert * K2A2n + sphi * K1A2n;
1295 const double HA2n = dzhor * K2A2n - cphi * K1A2n;
1296 const double DA2n = VA2n + HA2n;
1297 const double VZA2n = VA2n + ring_unit * K2A2n;
1298 const double HZA2n = HA2n + ring_unit * K2A2n;
1299 const double DZA2n = DA2n + ring_unit * K2A2n;
1300 const double VA3n = dzvert * K2A3n + sphi * K1A3n;
1301 const double HA3n = dzhor * K2A3n - cphi * K1A3n;
1302 const double DA3n = VA3n + HA3n;
1303 const double VZA3n = VA3n + ring_unit * K2A3n;
1304 const double HZA3n = HA3n + ring_unit * K2A3n;
1305 const double DZA3n = DA3n + ring_unit * K2A3n;
1307 const double VP0 = dzvert * K2P0 + sphi * K1P0;
1308 const double HP0 = dzhor * K2P0 - cphi * K1P0;
1309 const double DP0 = VP0 + HP0;
1310 const double VZP0 = VP0 + ring_unit * K2P0;
1311 const double HZP0 = HP0 + ring_unit * K2P0;
1312 const double DZP0 = DP0 + ring_unit * K2P0;
1313 const double VP1 = dzvert * K2P1 + sphi * K1P1;
1314 const double HP1 = dzhor * K2P1 - cphi * K1P1;
1315 const double DP1 = VP1 + HP1;
1316 const double VZP1 = VP1 + ring_unit * K2P1;
1317 const double HZP1 = HP1 + ring_unit * K2P1;
1318 const double DZP1 = DP1 + ring_unit * K2P1;
1319 const double VP2 = dzvert * K2P2 + sphi * K1P2;
1320 const double HP2 = dzhor * K2P2 - cphi * K1P2;
1321 const double DP2 = VP2 + HP2;
1322 const double VZP2 = VP2 + ring_unit * K2P2;
1323 const double HZP2 = HP2 + ring_unit * K2P2;
1324 const double DZP2 = DP2 + ring_unit * K2P2;
1325 const double VP3 = dzvert * K2P3 + sphi * K1P3;
1326 const double HP3 = dzhor * K2P3 - cphi * K1P3;
1327 const double DP3 = VP3 + HP3;
1328 const double VZP3 = VP3 + ring_unit * K2P3;
1329 const double HZP3 = HP3 + ring_unit * K2P3;
1330 const double DZP3 = DP3 + ring_unit * K2P3;
1332 const double VP0n = dzvert * K2P0n + sphi * K1P0n;
1333 const double HP0n = dzhor * K2P0n - cphi * K1P0n;
1334 const double DP0n = VP0n + HP0n;
1335 const double VZP0n = VP0n + ring_unit * K2P0n;
1336 const double HZP0n = HP0n + ring_unit * K2P0n;
1337 const double DZP0n = DP0n + ring_unit * K2P0n;
1338 const double VP1n = dzvert * K2P1n + sphi * K1P1n;
1339 const double HP1n = dzhor * K2P1n - cphi * K1P1n;
1340 const double DP1n = VP1n + HP1n;
1341 const double VZP1n = VP1n + ring_unit * K2P1n;
1342 const double HZP1n = HP1n + ring_unit * K2P1n;
1343 const double DZP1n = DP1n + ring_unit * K2P1n;
1344 const double VP2n = dzvert * K2P2n + sphi * K1P2n;
1345 const double HP2n = dzhor * K2P2n - cphi * K1P2n;
1346 const double DP2n = VP2n + HP2n;
1347 const double VZP2n = VP2n + ring_unit * K2P2n;
1348 const double HZP2n = HP2n + ring_unit * K2P2n;
1349 const double DZP2n = DP2n + ring_unit * K2P2n;
1350 const double VP3n = dzvert * K2P3n + sphi * K1P3n;
1351 const double HP3n = dzhor * K2P3n - cphi * K1P3n;
1352 const double DP3n = VP3n + HP3n;
1353 const double VZP3n = VP3n + ring_unit * K2P3n;
1354 const double HZP3n = HP3n + ring_unit * K2P3n;
1355 const double DZP3n = DP3n + ring_unit * K2P3n;
1359 double UpA0 = Projptr[0][0][0][1] + ds * K1A0 + dz * K2A0;
1360 double UpA1 = Projptr[0][1][0][1] + ds * K1A1 + dz * K2A1;
1361 double UpA2 = Projptr[0][2][0][1] + ds * K1A2 + dz * K2A2;
1362 double UpA3 = Projptr[0][3][0][1] + ds * K1A3 + dz * K2A3;
1364 double UpA0n = Projptr[1][0][0][1] + ds * K1A0n + dz * K2A0n;
1365 double UpA1n = Projptr[1][1][0][1] + ds * K1A1n + dz * K2A1n;
1366 double UpA2n = Projptr[1][2][0][1] + ds * K1A2n + dz * K2A2n;
1367 double UpA3n = Projptr[1][3][0][1] + ds * K1A3n + dz * K2A3n;
1369 double UpP0 = Projptr[0][0][1][1] + ds * K1P0 + dz * K2P0;
1370 double UpP1 = Projptr[0][1][1][1] + ds * K1P1 + dz * K2P1;
1371 double UpP2 = Projptr[0][2][1][1] + ds * K1P2 + dz * K2P2;
1372 double UpP3 = Projptr[0][3][1][1] + ds * K1P3 + dz * K2P3;
1374 double UpP0n = Projptr[1][0][1][1] + ds * K1P0n + dz * K2P0n;
1375 double UpP1n = Projptr[1][1][1][1] + ds * K1P1n + dz * K2P1n;
1376 double UpP2n = Projptr[1][2][1][1] + ds * K1P2n + dz * K2P2n;
1377 double UpP3n = Projptr[1][3][1][1] + ds * K1P3n + dz * K2P3n;
1381 const double ZplusKorrA0 = K2A0;
1382 const double ZplusKorrA1 = K2A1;
1383 const double ZplusKorrA2 = K2A2;
1384 const double ZplusKorrA3 = K2A3;
1386 const double ZplusKorrA0n = K2A0n;
1387 const double ZplusKorrA1n = K2A1n;
1388 const double ZplusKorrA2n = K2A2n;
1389 const double ZplusKorrA3n = K2A3n;
1391 const double ZplusKorrP0 = K2P0;
1392 const double ZplusKorrP1 = K2P1;
1393 const double ZplusKorrP2 = K2P2;
1394 const double ZplusKorrP3 = K2P3;
1396 const double ZplusKorrP0n = K2P0n;
1397 const double ZplusKorrP1n = K2P1n;
1398 const double ZplusKorrP2n = K2P2n;
1399 const double ZplusKorrP3n = K2P3n;
1403 const double VA0a0 = +sphi * K1A0;
1404 const double HA0a0 = -cphi * K1A0;
1405 const double DA0a0 = VA0a0 + HA0a0;
1406 const double VA1a0 = +sphi * K1A1;
1407 const double HA1a0 = -cphi * K1A1;
1408 const double DA1a0 = VA1a0 + HA1a0;
1409 const double VA2a0 = +sphi * K1A2;
1410 const double HA2a0 = -cphi * K1A2;
1411 const double DA2a0 = VA2a0 + HA2a0;
1412 const double VA3a0 = +sphi * K1A3;
1413 const double HA3a0 = -cphi * K1A3;
1414 const double DA3a0 = VA3a0 + HA3a0;
1416 const double VA0na0 = +sphi * K1A0n;
1417 const double HA0na0 = -cphi * K1A0n;
1418 const double DA0na0 = VA0na0 + HA0na0;
1419 const double VA1na0 = +sphi * K1A1n;
1420 const double HA1na0 = -cphi * K1A1n;
1421 const double DA1na0 = VA1na0 + HA1na0;
1422 const double VA2na0 = +sphi * K1A2n;
1423 const double HA2na0 = -cphi * K1A2n;
1424 const double DA2na0 = VA2na0 + HA2na0;
1425 const double VA3na0 = +sphi * K1A3n;
1426 const double HA3na0 = -cphi * K1A3n;
1427 const double DA3na0 = VA3na0 + HA3na0;
1429 const double VP0a0 = +sphi * K1P0;
1430 const double HP0a0 = -cphi * K1P0;
1431 const double DP0a0 = VP0a0 + HP0a0;
1432 const double VP1a0 = +sphi * K1P1;
1433 const double HP1a0 = -cphi * K1P1;
1434 const double DP1a0 = VP1a0 + HP1a0;
1435 const double VP2a0 = +sphi * K1P2;
1436 const double HP2a0 = -cphi * K1P2;
1437 const double DP2a0 = VP2a0 + HP2a0;
1438 const double VP3a0 = +sphi * K1P3;
1439 const double HP3a0 = -cphi * K1P3;
1440 const double DP3a0 = VP3a0 + HP3a0;
1442 const double VP0na0 = +sphi * K1P0n;
1443 const double HP0na0 = -cphi * K1P0n;
1444 const double DP0na0 = VP0na0 + HP0na0;
1445 const double VP1na0 = +sphi * K1P1n;
1446 const double HP1na0 = -cphi * K1P1n;
1447 const double DP1na0 = VP1na0 + HP1na0;
1448 const double VP2na0 = +sphi * K1P2n;
1449 const double HP2na0 = -cphi * K1P2n;
1450 const double DP2na0 = VP2na0 + HP2na0;
1451 const double VP3na0 = +sphi * K1P3n;
1452 const double HP3na0 = -cphi * K1P3n;
1453 const double DP3na0 = VP3na0 + HP3na0;
1455 const double VA0a1 = +sphi * (K1A0 + K3A0);
1456 const double HA0a1 = -cphi * (K1A0 + K3A0);
1457 const double DA0a1 = VA0a1 + HA0a1;
1458 const double VA1a1 = +sphi * (K1A1 + K3A1);
1459 const double HA1a1 = -cphi * (K1A1 + K3A1);
1460 const double DA1a1 = VA1a1 + HA1a1;
1461 const double VA2a1 = +sphi * (K1A2 + K3A2);
1462 const double HA2a1 = -cphi * (K1A2 + K3A2);
1463 const double DA2a1 = VA2a1 + HA2a1;
1464 const double VA3a1 = +sphi * (K1A3 + K3A3);
1465 const double HA3a1 = -cphi * (K1A3 + K3A3);
1466 const double DA3a1 = VA3a1 + HA3a1;
1468 const double VA0na1 = +sphi * (K1A0n + K3A0n);
1469 const double HA0na1 = -cphi * (K1A0n + K3A0n);
1470 const double DA0na1 = VA0na1 + HA0na1;
1471 const double VA1na1 = +sphi * (K1A1n + K3A1n);
1472 const double HA1na1 = -cphi * (K1A1n + K3A1n);
1473 const double DA1na1 = VA1na1 + HA1na1;
1474 const double VA2na1 = +sphi * (K1A2n + K3A2n);
1475 const double HA2na1 = -cphi * (K1A2n + K3A2n);
1476 const double DA2na1 = VA2na1 + HA2na1;
1477 const double VA3na1 = +sphi * (K1A3n + K3A3n);
1478 const double HA3na1 = -cphi * (K1A3n + K3A3n);
1479 const double DA3na1 = VA3na1 + HA3na1;
1481 const double VP0a1 = +sphi * (K1P0 + K3P0);
1482 const double HP0a1 = -cphi * (K1P0 + K3P0);
1483 const double DP0a1 = VP0a1 + HP0a1;
1484 const double VP1a1 = +sphi * (K1P1 + K3P1);
1485 const double HP1a1 = -cphi * (K1P1 + K3P1);
1486 const double DP1a1 = VP1a1 + HP1a1;
1487 const double VP2a1 = +sphi * (K1P2 + K3P2);
1488 const double HP2a1 = -cphi * (K1P2 + K3P2);
1489 const double DP2a1 = VP2a1 + HP2a1;
1490 const double VP3a1 = +sphi * (K1P3 + K3P3);
1491 const double HP3a1 = -cphi * (K1P3 + K3P3);
1492 const double DP3a1 = VP3a1 + HP3a1;
1494 const double VP0na1 = +sphi * (K1P0n + K3P0n);
1495 const double HP0na1 = -cphi * (K1P0n + K3P0n);
1496 const double DP0na1 = VP0na1 + HP0na1;
1497 const double VP1na1 = +sphi * (K1P1n + K3P1n);
1498 const double HP1na1 = -cphi * (K1P1n + K3P1n);
1499 const double DP1na1 = VP1na1 + HP1na1;
1500 const double VP2na1 = +sphi * (K1P2n + K3P2n);
1501 const double HP2na1 = -cphi * (K1P2n + K3P2n);
1502 const double DP2na1 = VP2na1 + HP2na1;
1503 const double VP3na1 = +sphi * (K1P3n + K3P3n);
1504 const double HP3na1 = -cphi * (K1P3n + K3P3n);
1505 const double DP3na1 = VP3na1 + HP3na1;
1507 const double VA0 = VA0a0 * 1.5 - VA0a1 / 2 + 2 * dzvert * K2A0;
1508 const double HA0 = HA0a0 * 1.5 - HA0a1 / 2 + 2 * dzhor * K2A0;
1509 const double DA0 = VA0 + HA0;
1510 const double VZA0 = VA0 + K2A0;
1511 const double HZA0 = HA0 + K2A0;
1512 const double DZA0 = DA0 + K2A0;
1513 const double VA1 = VA1a0 * 1.5 - VA1a1 / 2 + 2 * dzvert * K2A1;
1514 const double HA1 = HA1a0 * 1.5 - HA1a1 / 2 + 2 * dzhor * K2A1;
1515 const double DA1 = VA1 + HA1;
1516 const double VZA1 = VA1 + K2A1;
1517 const double HZA1 = HA1 + K2A1;
1518 const double DZA1 = DA1 + K2A1;
1519 const double VA2 = VA2a0 * 1.5 - VA2a1 / 2 + 2 * dzvert * K2A2;
1520 const double HA2 = HA2a0 * 1.5 - HA2a1 / 2 + 2 * dzhor * K2A2;
1521 const double DA2 = VA2 + HA2;
1522 const double VZA2 = VA2 + K2A2;
1523 const double HZA2 = HA2 + K2A2;
1524 const double DZA2 = DA2 + K2A2;
1525 const double VA3 = VA3a0 * 1.5 - VA3a1 / 2 + 2 * dzvert * K2A3;
1526 const double HA3 = HA3a0 * 1.5 - HA3a1 / 2 + 2 * dzhor * K2A3;
1527 const double DA3 = VA3 + HA3;
1528 const double VZA3 = VA3 + K2A3;
1529 const double HZA3 = HA3 + K2A3;
1530 const double DZA3 = DA3 + K2A3;
1532 const double VA0n = VA0na0 * 1.5 - VA0na1 / 2 + 2 * dzvert * K2A0n;
1533 const double HA0n = HA0na0 * 1.5 - HA0na1 / 2 + 2 * dzhor * K2A0n;
1534 const double DA0n = VA0n + HA0n;
1535 const double VZA0n = VA0n + K2A0n;
1536 const double HZA0n = HA0n + K2A0n;
1537 const double DZA0n = DA0n + K2A0n;
1538 const double VA1n = VA1na0 * 1.5 - VA1na1 / 2 + 2 * dzvert * K2A1n;
1539 const double HA1n = HA1na0 * 1.5 - HA1na1 / 2 + 2 * dzhor * K2A1n;
1540 const double DA1n = VA1n + HA1n;
1541 const double VZA1n = VA1n + K2A1n;
1542 const double HZA1n = HA1n + K2A1n;
1543 const double DZA1n = DA1n + K2A1n;
1544 const double VA2n = VA2na0 * 1.5 - VA2na1 / 2 + 2 * dzvert * K2A2n;
1545 const double HA2n = HA2na0 * 1.5 - HA2na1 / 2 + 2 * dzhor * K2A2n;
1546 const double DA2n = VA2n + HA2n;
1547 const double VZA2n = VA2n + K2A2n;
1548 const double HZA2n = HA2n + K2A2n;
1549 const double DZA2n = DA2n + K2A2n;
1550 const double VA3n = VA3na0 * 1.5 - VA3na1 / 2 + 2 * dzvert * K2A3n;
1551 const double HA3n = HA3na0 * 1.5 - HA3na1 / 2 + 2 * dzhor * K2A3n;
1552 const double DA3n = VA3n + HA3n;
1553 const double VZA3n = VA3n + K2A3n;
1554 const double HZA3n = HA3n + K2A3n;
1555 const double DZA3n = DA3n + K2A3n;
1557 const double VP0 = VP0a0 * 1.5 - VP0a1 / 2 + 2 * dzvert * K2P0;
1558 const double HP0 = HP0a0 * 1.5 - HP0a1 / 2 + 2 * dzhor * K2P0;
1559 const double DP0 = VP0 + HP0;
1560 const double VZP0 = VP0 + K2P0;
1561 const double HZP0 = HP0 + K2P0;
1562 const double DZP0 = DP0 + K2P0;
1563 const double VP1 = VP1a0 * 1.5 - VP1a1 / 2 + 2 * dzvert * K2P1;
1564 const double HP1 = HP1a0 * 1.5 - HP1a1 / 2 + 2 * dzhor * K2P1;
1565 const double DP1 = VP1 + HP1;
1566 const double VZP1 = VP1 + K2P1;
1567 const double HZP1 = HP1 + K2P1;
1568 const double DZP1 = DP1 + K2P1;
1569 const double VP2 = VP2a0 * 1.5 - VP2a1 / 2 + 2 * dzvert * K2P2;
1570 const double HP2 = HP2a0 * 1.5 - HP2a1 / 2 + 2 * dzhor * K2P2;
1571 const double DP2 = VP2 + HP2;
1572 const double VZP2 = VP2 + K2P2;
1573 const double HZP2 = HP2 + K2P2;
1574 const double DZP2 = DP2 + K2P2;
1575 const double VP3 = VP3a0 * 1.5 - VP3a1 / 2 + 2 * dzvert * K2P3;
1576 const double HP3 = HP3a0 * 1.5 - HP3a1 / 2 + 2 * dzhor * K2P3;
1577 const double DP3 = VP3 + HP3;
1578 const double VZP3 = VP3 + K2P3;
1579 const double HZP3 = HP3 + K2P3;
1580 const double DZP3 = DP3 + K2P3;
1582 const double VP0n = VP0na0 * 1.5 - VP0na1 / 2 + 2 * dzvert * K2P0n;
1583 const double HP0n = HP0na0 * 1.5 - HP0na1 / 2 + 2 * dzhor * K2P0n;
1584 const double DP0n = VP0n + HP0n;
1585 const double VZP0n = VP0n + K2P0n;
1586 const double HZP0n = HP0n + K2P0n;
1587 const double DZP0n = DP0n + K2P0n;
1588 const double VP1n = VP1na0 * 1.5 - VP1na1 / 2 + 2 * dzvert * K2P1n;
1589 const double HP1n = HP1na0 * 1.5 - HP1na1 / 2 + 2 * dzhor * K2P1n;
1590 const double DP1n = VP1n + HP1n;
1591 const double VZP1n = VP1n + K2P1n;
1592 const double HZP1n = HP1n + K2P1n;
1593 const double DZP1n = DP1n + K2P1n;
1594 const double VP2n = VP2na0 * 1.5 - VP2na1 / 2 + 2 * dzvert * K2P2n;
1595 const double HP2n = HP2na0 * 1.5 - HP2na1 / 2 + 2 * dzhor * K2P2n;
1596 const double DP2n = VP2n + HP2n;
1597 const double VZP2n = VP2n + K2P2n;
1598 const double HZP2n = HP2n + K2P2n;
1599 const double DZP2n = DP2n + K2P2n;
1600 const double VP3n = VP3na0 * 1.5 - VP3na1 / 2 + 2 * dzvert * K2P3n;
1601 const double HP3n = HP3na0 * 1.5 - HP3na1 / 2 + 2 * dzhor * K2P3n;
1602 const double DP3n = VP3n + HP3n;
1603 const double VZP3n = VP3n + K2P3n;
1604 const double HZP3n = HP3n + K2P3n;
1605 const double DZP3n = DP3n + K2P3n;
1609 double A0a0 = Projptr[0][0][0][1] + ds * K1A0;
1610 double A0a1 = Projptr[0][0][0][3] + ds * (K1A0 + K3A0);
1611 double A2a0 = Projptr[0][2][0][1] + ds * K1A2;
1612 double A2a1 = Projptr[0][2][0][3] + ds * (K1A2 + K3A2);
1614 double P0na0 = Projptr[1][0][1][1] + ds * K1P0n;
1615 double P0na1 = Projptr[1][0][1][3] + ds * (K1P0n + K3P0n);
1616 double P2na0 = Projptr[1][2][1][1] + ds * K1P2n;
1617 double P2na1 = Projptr[1][2][1][3] + ds * (K1P2n + K3P2n);
1619 double A0na0 = Projptr[1][0][0][1] + ds * K1A0n;
1620 double A0na1 = Projptr[1][0][0][3] + ds * (K1A0n + K3A0n);
1621 double A2na0 = Projptr[1][2][0][1] + ds * K1A2n;
1622 double A2na1 = Projptr[1][2][0][3] + ds * (K1A2n + K3A2n);
1624 double P0a0 = Projptr[0][0][1][1] + ds * K1P0;
1625 double P0a1 = Projptr[0][0][1][3] + ds * (K1P0 + K3P0);
1626 double P2a0 = Projptr[0][2][1][1] + ds * K1P2;
1627 double P2a1 = Projptr[0][2][1][3] + ds * (K1P2 + K3P2);
1629 double A1a0 = Projptr[0][1][0][1] + ds * K1A1;
1630 double A1a1 = Projptr[0][1][0][3] + ds * (K1A1 + K3A1);
1631 double A3a0 = Projptr[0][3][0][1] + ds * K1A3;
1632 double A3a1 = Projptr[0][3][0][3] + ds * (K1A3 + K3A3);
1634 double P1na0 = Projptr[1][1][1][1] + ds * K1P1n;
1635 double P1na1 = Projptr[1][1][1][3] + ds * (K1P1n + K3P1n);
1636 double P3na0 = Projptr[1][3][1][1] + ds * K1P3n;
1637 double P3na1 = Projptr[1][3][1][3] + ds * (K1P3n + K3P3n);
1639 double A1na0 = Projptr[1][1][0][1] + ds * K1A1n;
1640 double A1na1 = Projptr[1][1][0][3] + ds * (K1A1n + K3A1n);
1641 double A3na0 = Projptr[1][3][0][1] + ds * K1A3n;
1642 double A3na1 = Projptr[1][3][0][3] + ds * (K1A3n + K3A3n);
1644 double P1a0 = Projptr[0][1][1][1] + ds * K1P1;
1645 double P1a1 = Projptr[0][1][1][3] + ds * (K1P1 + K3P1);
1646 double P3a0 = Projptr[0][3][1][1] + ds * K1P3;
1647 double P3a1 = Projptr[0][3][1][3] + ds * (K1P3 + K3P3);
1649 double UpA0 = 2 * (Projptr[0][0][0][1] + ds * K1A0 + dz * K2A0) - (A0a0 + A0a1) / 2;
1650 double UpA1 = 2 * (Projptr[0][1][0][1] + ds * K1A1 + dz * K2A1) - (A1a0 + A1a1) / 2;
1651 double UpA2 = 2 * (Projptr[0][2][0][1] + ds * K1A2 + dz * K2A2) - (A2a0 + A2a1) / 2;
1652 double UpA3 = 2 * (Projptr[0][3][0][1] + ds * K1A3 + dz * K2A3) - (A3a0 + A3a1) / 2;
1654 double UpA0n = 2 * (Projptr[1][0][0][1] + ds * K1A0n + dz * K2A0n) - (A0na0 + A0na1) / 2;
1655 double UpA1n = 2 * (Projptr[1][1][0][1] + ds * K1A1n + dz * K2A1n) - (A1na0 + A1na1) / 2;
1656 double UpA2n = 2 * (Projptr[1][2][0][1] + ds * K1A2n + dz * K2A2n) - (A2na0 + A2na1) / 2;
1657 double UpA3n = 2 * (Projptr[1][3][0][1] + ds * K1A3n + dz * K2A3n) - (A3na0 + A3na1) / 2;
1659 double UpP0 = 2 * (Projptr[0][0][1][1] + ds * K1P0 + dz * K2P0) - (P0a0 + P0a1) / 2;
1660 double UpP1 = 2 * (Projptr[0][1][1][1] + ds * K1P1 + dz * K2P1) - (P1a0 + P1a1) / 2;
1661 double UpP2 = 2 * (Projptr[0][2][1][1] + ds * K1P2 + dz * K2P2) - (P2a0 + P2a1) / 2;
1662 double UpP3 = 2 * (Projptr[0][3][1][1] + ds * K1P3 + dz * K2P3) - (P3a0 + P3a1) / 2;
1664 double UpP0n = 2 * (Projptr[1][0][1][1] + ds * K1P0n + dz * K2P0n) - (P0na0 + P0na1) / 2;
1665 double UpP1n = 2 * (Projptr[1][1][1][1] + ds * K1P1n + dz * K2P1n) - (P1na0 + P1na1) / 2;
1666 double UpP2n = 2 * (Projptr[1][2][1][1] + ds * K1P2n + dz * K2P2n) - (P2na0 + P2na1) / 2;
1667 double UpP3n = 2 * (Projptr[1][3][1][1] + ds * K1P3n + dz * K2P3n) - (P3na0 + P3na1) / 2;
1681 = (2 * num_planes_per_axial_pos * (ring0 + 0.5) + num_planes_per_physical_ring * delta + 2 * axial_pos_to_z_offset - Z);
1683 Q = (int)floor(Qf + 0.5);
1684 assert(fabs(Q - Qf) < 10E-4);
1687 dzdiag = dzvert + dzhor;
1688 dsdiag = -cphi + sphi;
1706 assert(dz <= ring_unit + epsilon);
1711 const int Zplus = Z + 1;
1712 const int Qmin = Q - 1;
1714#if PIECEWISE_INTERPOLATION
1716 const double twodsdz = 2 * ds * dz;
1717 const double twodsdz2 = 2 * ds * (dz + 0.5);
1719 const bool do_s_symmetry = (s != 0 || fabs(ds) > epsilon);
1721 if (Z >= minplane && Z <= maxplane)
1723 image[Z][Y][X] += (dz <= 0.25) ? A0a0 : UpA0 + twodsdz * K3A0;
1724 image[Z][X][-Y] += (dz <= 0.25) ? A2a0 : UpA2 + twodsdz * K3A2;
1725 image[Z][X][Y] += (dz <= 0.25) ? A1na0 : UpA1n + twodsdz * K3A1n;
1726 image[Z][Y][-X] += (dz <= 0.25) ? A3na0 : UpA3n + twodsdz * K3A3n;
1729 image[Z][-X][-Y] += (dz <= 0.25) ? P1a0 : UpP1 + twodsdz * K3P1;
1730 image[Z][-Y][X] += (dz <= 0.25) ? P3a0 : UpP3 + twodsdz * K3P3;
1731 image[Z][-Y][-X] += (dz <= 0.25) ? P0na0 : UpP0n + twodsdz * K3P0n;
1732 image[Z][-X][Y] += (dz <= 0.25) ? P2na0 : UpP2n + twodsdz * K3P2n;
1735 if (Zplus >= minplane && Zplus <= maxplane)
1737 image[Zplus][Y][X] += (dz >= 0.25) ? A0a1 : UpA0 + twodsdz2 * K3A0 + ZplusKorrA0;
1738 image[Zplus][X][-Y] += (dz >= 0.25) ? A2a1 : UpA2 + twodsdz2 * K3A2 + ZplusKorrA2;
1739 image[Zplus][X][Y] += (dz >= 0.25) ? A1na1 : UpA1n + twodsdz2 * K3A1n + ZplusKorrA1n;
1740 image[Zplus][Y][-X] += (dz >= 0.25) ? A3na1 : UpA3n + twodsdz2 * K3A3n + ZplusKorrA3n;
1743 image[Zplus][-X][-Y] += (dz >= 0.25) ? P1a1 : UpP1 + twodsdz2 * K3P1 + ZplusKorrP1;
1744 image[Zplus][-Y][X] += (dz >= 0.25) ? P3a1 : UpP3 + twodsdz2 * K3P3 + ZplusKorrP3;
1745 image[Zplus][-Y][-X] += (dz >= 0.25) ? P0na1 : UpP0n + twodsdz2 * K3P0n + ZplusKorrP0n;
1746 image[Zplus][-X][Y] += (dz >= 0.25) ? P2na1 : UpP2n + twodsdz2 * K3P2n + ZplusKorrP2n;
1749 if (Q >= minplane && Q <= maxplane)
1751 image[Q][Y][-X] += (dz <= 0.25) ? A3a0 : UpA3 + twodsdz * K3A3;
1752 image[Q][Y][X] += (dz <= 0.25) ? A0na0 : UpA0n + twodsdz * K3A0n;
1753 image[Q][X][-Y] += (dz <= 0.25) ? A2na0 : UpA2n + twodsdz * K3A2n;
1754 image[Q][X][Y] += (dz <= 0.25) ? A1a0 : UpA1 + twodsdz * K3A1;
1757 image[Q][-Y][-X] += (dz <= 0.25) ? P0a0 : UpP0 + twodsdz * K3P0;
1758 image[Q][-X][Y] += (dz <= 0.25) ? P2a0 : UpP2 + twodsdz * K3P2;
1759 image[Q][-X][-Y] += (dz <= 0.25) ? P1na0 : UpP1n + twodsdz * K3P1n;
1760 image[Q][-Y][X] += (dz <= 0.25) ? P3na0 : UpP3n + twodsdz * K3P3n;
1763 if (Qmin >= minplane && Qmin <= maxplane)
1765 image[Qmin][Y][-X] += (dz >= 0.25) ? A3a1 : UpA3 + twodsdz2 * K3A3 + ZplusKorrA3;
1766 image[Qmin][Y][X] += (dz >= 0.25) ? A0na1 : UpA0n + twodsdz2 * K3A0n + ZplusKorrA0n;
1767 image[Qmin][X][-Y] += (dz >= 0.25) ? A2na1 : UpA2n + twodsdz2 * K3A2n + ZplusKorrA2n;
1768 image[Qmin][X][Y] += (dz >= 0.25) ? A1a1 : UpA1 + twodsdz2 * K3A1 + ZplusKorrA1;
1771 image[Qmin][-Y][-X] += (dz >= 0.25) ? P0a1 : UpP0 + twodsdz2 * K3P0 + ZplusKorrP0;
1772 image[Qmin][-X][Y] += (dz >= 0.25) ? P2a1 : UpP2 + twodsdz2 * K3P2 + ZplusKorrP2;
1773 image[Qmin][-X][-Y] += (dz >= 0.25) ? P1na1 : UpP1n + twodsdz2 * K3P1n + ZplusKorrP1n;
1774 image[Qmin][-Y][X] += (dz >= 0.25) ? P3na1 : UpP3n + twodsdz2 * K3P3n + ZplusKorrP3n;
1779 const double dsdz = ds * dz;
1780 const double dsdz2 = ds * (dz + 0.5);
1782 const bool do_s_symmetry = (s != 0 || fabs(ds) > epsilon);
1784 if (Z >= minplane && Z <= maxplane)
1786 image[Z][Y][X] += UpA0 + dsdz * K3A0;
1787 image[Z][X][-Y] += UpA2 + dsdz * K3A2;
1788 image[Z][X][Y] += UpA1n + dsdz * K3A1n;
1789 image[Z][Y][-X] += UpA3n + dsdz * K3A3n;
1792 image[Z][-X][-Y] += UpP1 + dsdz * K3P1;
1793 image[Z][-Y][X] += UpP3 + dsdz * K3P3;
1794 image[Z][-Y][-X] += UpP0n + dsdz * K3P0n;
1795 image[Z][-X][Y] += UpP2n + dsdz * K3P2n;
1798 if (Zplus >= minplane && Zplus <= maxplane)
1800 image[Zplus][Y][X] += UpA0 + dsdz2 * K3A0 + ZplusKorrA0;
1801 image[Zplus][X][-Y] += UpA2 + dsdz2 * K3A2 + ZplusKorrA2;
1802 image[Zplus][X][Y] += UpA1n + dsdz2 * K3A1n + ZplusKorrA1n;
1803 image[Zplus][Y][-X] += UpA3n + dsdz2 * K3A3n + ZplusKorrA3n;
1806 image[Zplus][-X][-Y] += UpP1 + dsdz2 * K3P1 + ZplusKorrP1;
1807 image[Zplus][-Y][X] += UpP3 + dsdz2 * K3P3 + ZplusKorrP3;
1808 image[Zplus][-Y][-X] += UpP0n + dsdz2 * K3P0n + ZplusKorrP0n;
1809 image[Zplus][-X][Y] += UpP2n + dsdz2 * K3P2n + ZplusKorrP2n;
1812 if (Q >= minplane && Q <= maxplane)
1814 image[Q][Y][-X] += UpA3 + dsdz * K3A3;
1815 image[Q][Y][X] += UpA0n + dsdz * K3A0n;
1816 image[Q][X][-Y] += UpA2n + dsdz * K3A2n;
1817 image[Q][X][Y] += UpA1 + dsdz * K3A1;
1820 image[Q][-Y][-X] += UpP0 + dsdz * K3P0;
1821 image[Q][-X][Y] += UpP2 + dsdz * K3P2;
1822 image[Q][-X][-Y] += UpP1n + dsdz * K3P1n;
1823 image[Q][-Y][X] += UpP3n + dsdz * K3P3n;
1826 if (Qmin >= minplane && Qmin <= maxplane)
1828 image[Qmin][Y][-X] += UpA3 + dsdz2 * K3A3 + ZplusKorrA3;
1829 image[Qmin][Y][X] += UpA0n + dsdz2 * K3A0n + ZplusKorrA0n;
1830 image[Qmin][X][-Y] += UpA2n + dsdz2 * K3A2n + ZplusKorrA2n;
1831 image[Qmin][X][Y] += UpA1 + dsdz2 * K3A1 + ZplusKorrA1;
1834 image[Qmin][-Y][-X] += UpP0 + dsdz2 * K3P0 + ZplusKorrP0;
1835 image[Qmin][-X][Y] += UpP2 + dsdz2 * K3P2 + ZplusKorrP2;
1836 image[Qmin][-X][-Y] += UpP1n + dsdz2 * K3P1n + ZplusKorrP1n;
1837 image[Qmin][-Y][X] += UpP3n + dsdz2 * K3P3n + ZplusKorrP3n;
1843 TMP2 = UpA0 + dz * TMP1;
1844 if (Z >= minplane && Z <= maxplane)
1845 image[Z][Y][X] += TMP2;
1849 if (Zplus >= minplane && Zplus <= maxplane && ring_unit == 0.5)
1850 image[Zplus][Y][X] += TMP2 + ring_unit * TMP1 + ZplusKorrA0;
1853 TMP2 = UpA1 + dz * TMP1;
1854 if (Q >= minplane && Q <= maxplane)
1855 image[Q][X][Y] += TMP2;
1858 if (Qmin >= minplane && Qmin <= maxplane && ring_unit == 0.5)
1859 image[Qmin][X][Y] += TMP2 + ring_unit * TMP1 + ZplusKorrA1;
1862 TMP2 = UpA2 + dz * TMP1;
1863 if (Z >= minplane && Z <= maxplane)
1864 image[Z][X][-Y] += TMP2;
1867 if (Zplus >= minplane && Zplus <= maxplane && ring_unit == 0.5)
1868 image[Zplus][X][-Y] += TMP2 + ring_unit * TMP1 + ZplusKorrA2;
1870 TMP2 = UpA3 + dz * TMP1;
1871 if (Q >= minplane && Q <= maxplane)
1872 image[Q][Y][-X] += TMP2;
1875 if (Qmin >= minplane && Qmin <= maxplane && ring_unit == 0.5)
1876 image[Qmin][Y][-X] += TMP2 + ring_unit * TMP1 + ZplusKorrA3;
1879 TMP2 = UpA0n + dz * TMP1;
1880 if (Q >= minplane && Q <= maxplane)
1881 image[Q][Y][X] += TMP2;
1884 if (Qmin >= minplane && Qmin <= maxplane && ring_unit == 0.5)
1885 image[Qmin][Y][X] += TMP2 + ring_unit * TMP1 + ZplusKorrA0n;
1887 TMP2 = UpA1n + dz * TMP1;
1888 if (Z >= minplane && Z <= maxplane)
1889 image[Z][X][Y] += TMP2;
1892 if (Zplus >= minplane && Zplus <= maxplane && ring_unit == 0.5)
1893 image[Zplus][X][Y] += TMP2 + ring_unit * TMP1 + ZplusKorrA1n;
1895 TMP2 = UpA2n + dz * TMP1;
1896 if (Q >= minplane && Q <= maxplane)
1897 image[Q][X][-Y] += TMP2;
1900 if (Qmin >= minplane && Qmin <= maxplane && ring_unit == 0.5)
1901 image[Qmin][X][-Y] += TMP2 + ring_unit * TMP1 + ZplusKorrA2n;
1903 TMP2 = UpA3n + dz * TMP1;
1904 if (Z >= minplane && Z <= maxplane)
1905 image[Z][Y][-X] += TMP2;
1908 if (Zplus >= minplane && Zplus <= maxplane && ring_unit == 0.5)
1909 image[Zplus][Y][-X] += TMP2 + ring_unit * TMP1 + ZplusKorrA3n;
1912 if (s != 0 || fabs(ds) > epsilon)
1915 TMP2 = UpP0 + dz * TMP1;
1916 if (Q >= minplane && Q <= maxplane)
1917 image[Q][-Y][-X] += TMP2;
1920 if (Qmin >= minplane && Qmin <= maxplane && ring_unit == 0.5)
1921 image[Qmin][-Y][-X] += TMP2 + ring_unit * TMP1 + ZplusKorrP0;
1923 TMP2 = UpP1 + dz * TMP1;
1924 if (Z >= minplane && Z <= maxplane)
1925 image[Z][-X][-Y] += TMP2;
1928 if (Zplus >= minplane && Zplus <= maxplane && ring_unit == 0.5)
1929 image[Zplus][-X][-Y] += TMP2 + ring_unit * TMP1 + ZplusKorrP1;
1931 TMP2 = UpP2 + dz * TMP1;
1932 if (Q >= minplane && Q <= maxplane)
1933 image[Q][-X][Y] += TMP2;
1936 if (Qmin >= minplane && Qmin <= maxplane && ring_unit == 0.5)
1937 image[Qmin][-X][Y] += TMP2 + ring_unit * TMP1 + ZplusKorrP2;
1939 TMP2 = UpP3 + dz * TMP1;
1940 if (Z >= minplane && Z <= maxplane)
1941 image[Z][-Y][X] += TMP2;
1944 if (Zplus >= minplane && Zplus <= maxplane && ring_unit == 0.5)
1945 image[Zplus][-Y][X] += TMP2 + ring_unit * TMP1 + ZplusKorrP3;
1948 TMP2 = UpP0n + dz * TMP1;
1949 if (Z >= minplane && Z <= maxplane)
1950 image[Z][-Y][-X] += TMP2;
1953 if (Zplus >= minplane && Zplus <= maxplane && ring_unit == 0.5)
1954 image[Zplus][-Y][-X] += TMP2 + ring_unit * TMP1 + ZplusKorrP0n;
1956 TMP2 = UpP1n + dz * TMP1;
1957 if (Q >= minplane && Q <= maxplane)
1958 image[Q][-X][-Y] += TMP2;
1961 if (Qmin >= minplane && Qmin <= maxplane && ring_unit == 0.5)
1962 image[Qmin][-X][-Y] += TMP2 + ring_unit * TMP1 + ZplusKorrP1n;
1964 TMP2 = UpP2n + dz * TMP1;
1965 if (Z >= minplane && Z <= maxplane)
1966 image[Z][-X][Y] += TMP2;
1969 if (Zplus >= minplane && Zplus <= maxplane && ring_unit == 0.5)
1970 image[Zplus][-X][Y] += TMP2 + ring_unit * TMP1 + ZplusKorrP2n;
1972 TMP2 = UpP3n + dz * TMP1;
1973 if (Q >= minplane && Q <= maxplane)
1974 image[Q][-Y][X] += TMP2;
1977 if (Qmin >= minplane && Qmin <= maxplane && ring_unit == 0.5)
1978 image[Qmin][-Y][X] += TMP2 + ring_unit * TMP1 + ZplusKorrP3n;
2014 while (dz < epsilon)
2023 UpA0n += HZA0n - HA0n;
2024 UpA1n += HZA1n - HA1n;
2025 UpA2n += HZA2n - HA2n;
2026 UpA3n += HZA3n - HA3n;
2031 UpP0n += HZP0n - HP0n;
2032 UpP1n += HZP1n - HP1n;
2033 UpP2n += HZP2n - HP2n;
2034 UpP3n += HZP3n - HP3n;
2058#if PIECEWISE_INTERPOLATION
2095 else if (ds < 1 - sphi)
2123 while (dz < epsilon)
2132 UpA0n += VZA0n - VA0n;
2133 UpA1n += VZA1n - VA1n;
2134 UpA2n += VZA2n - VA2n;
2135 UpA3n += VZA3n - VA3n;
2140 UpP0n += VZP0n - VP0n;
2141 UpP1n += VZP1n - VP1n;
2142 UpP2n += VZP2n - VP2n;
2143 UpP3n += VZP3n - VP3n;
2166#if PIECEWISE_INTERPOLATION
2231 while (dz < epsilon)
2240 UpA0n += DZA0n - DA0n;
2241 UpA1n += DZA1n - DA1n;
2242 UpA2n += DZA2n - DA2n;
2243 UpA3n += DZA3n - DA3n;
2248 UpP0n += DZP0n - DP0n;
2249 UpP1n += DZP1n - DP1n;
2250 UpP2n += DZP2n - DP2n;
2251 UpP3n += DZP3n - DP3n;
2275#if PIECEWISE_INTERPOLATION
2312 proj_data_info_sptr, delta, cphi, sphi, s, ring0, X, Y, Z, ds, dz, num_planes_per_axial_pos, axial_pos_to_z_offset);
2314 }
while ((X * X + Y * Y <= image_rad * image_rad) && (Z <= maxplane || Q >= minplane));
2320find_start_values(
const shared_ptr<const ProjDataInfoCylindricalArcCorr> proj_data_info_sptr,
2326 const float image_rad,
2335 const float num_planes_per_axial_pos,
2336 const float axial_pos_to_z_offset)
2340 const double d_p = proj_data_info_sptr->get_tangential_sampling();
2343 const double d_xy = proj_data_info_sptr->get_tangential_sampling();
2345 const double R2 =
square(proj_data_info_sptr->get_ring_radius());
2347 const double R2p = R2 / d_xy / d_xy;
2350 const int num_planes_per_physical_ring = 2;
2351 assert(fabs(d_sl * num_planes_per_physical_ring / proj_data_info_sptr->get_ring_spacing() - 1) < 10E-4);
2365 int rpix =
round(image_rad - 1);
2366 const double r2 = rpix * rpix * d_xy * d_xy;
2371 const double t = s + 0.5;
2376 return Succeeded::no;
2379 const double root = sqrt(rpix * rpix - t * t);
2380 const double X1f = t * cphi + sphi * root;
2382 const double Y1f = t * sphi - cphi * root;
2386 X1 = (int)floor(X1f + 0.5);
2388 Y1 = (int)floor(Y1f + 0.5);
2396 ds = X1 * cphi + Y1 * sphi - s;
2454 const double t2dp2 = t * t * d_p * d_p;
2458 if (t2dp2 >= R2 || t2dp2 > r2)
2459 return Succeeded::no;
2461 const double root1 = sqrt(R2 - t2dp2);
2462 const double root2 = sqrt(r2 - t2dp2);
2470 const double Z1f = num_planes_per_axial_pos * (ring0 + 0.5) + axial_pos_to_z_offset
2471 + num_planes_per_physical_ring * delta / 2 * (1 - root2 / root1);
2474 Z1 = (int)floor(Z1f);
2482 const double root = sqrt(R2p - t * t);
2487 = (Z1 - num_planes_per_physical_ring * delta / 2 * ((-X1 * sphi + Y1 * cphi) / root + 1) - axial_pos_to_z_offset)
2488 / num_planes_per_axial_pos;
2504 if (dz >= 1. / num_planes_per_axial_pos)
2506 while (dz >= 1. / num_planes_per_axial_pos)
2510 dz -= 1. / num_planes_per_axial_pos;
2515 while (dz < epsilon)
2519 dz += 1. / num_planes_per_axial_pos;
2528 dzvert = -delta * cphi / root / num_planes_per_axial_pos;
2529 dzhor = -delta * sphi / root / num_planes_per_axial_pos;
2532 return Succeeded::yes;
Declares class stir::BackProjectorByBinUsingInterpolation.
Declaration of class stir::ProjDataInfoCylindricalArcCorr.
Declaration of class stir::ProjDataInfo.
Declaration of class stir::Succeeded.
defines the stir::VoxelsOnCartesianGrid class
Declaration of stir::error()
void warning(const char *const s,...)
Print warning with format string a la printf.
Definition warning.cxx:41
NUMBER square(const NUMBER &x)
returns the square of a number, templated.
Definition common.h:154
int round(const float x)
Implements rounding of floating point numbers.
Definition round.inl:59
Declaration of the stir::round functions.
Declaration of stir::warning()