131 cout <<
"This projector is a line projector that uses linear interpolation between pixels." << endl;
132 cout <<
"It is implemented from the following published paper:" << endl;
133 cout <<
"P. M. Joseph, \"An improved algorithm for reprojecting rays through pixel images\", IEEE Trans. Med. Imaging, vol. 1, pp. 192-6, 1982." << endl;
157 if (
m_verbose>=2)
Cout(
"iProjectorJoseph::InitializeSpecific() -> Use Joseph projector" << endl);
168 INTNB nElts = ( mp_nbVox[ 0 ] + 2 ) * ( mp_nbVox[ 1 ] + 2 ) * ( mp_nbVox[ 2 ] + 2 );
170 ::memset(
mp_maskPad, 0,
sizeof( uint8_t ) * nElts );
171 for(
INTNB k = 1; k < mp_nbVox[ 2 ] + 1; ++k )
173 for(
INTNB j = 1; j < mp_nbVox[ 1 ] + 1; ++j )
175 for(
INTNB i = 1; i < mp_nbVox[ 0 ] + 1; ++i )
177 mp_maskPad[ i + j * ( ( mp_nbVox[ 0 ] + 2 ) ) + k * ( mp_nbVox[ 0 ] + 2 ) * ( mp_nbVox[ 1 ] + 2 ) ] = 1;
183 HPFLTNB tolerance_factor = 1.e-4;
209 max_nb_voxels_in_dimension *= 4;
211 return max_nb_voxels_in_dimension;
224 Cerr(
"***** iProjectorJoseph::ProjectWithoutTOF() -> Called while not initialized !" << endl);
229 #ifdef CASTOR_VERBOSE
232 string direction =
"";
233 if (a_direction==
FORWARD) direction =
"forward";
234 else direction =
"backward";
235 Cout(
"iProjectorJoseph::Project without TOF -> Project line '" << ap_ProjectionLine <<
"' in " << direction <<
" direction" << endl);
245 event2[ 0 ] - event1[ 0 ],
246 event2[ 1 ] - event1[ 1 ],
247 event2[ 2 ] - event1[ 2 ]
259 HPFLTNB alphaMin = 0.0, alphaMax = 1.0;
262 HPFLTNB pos[ 3 ] = { 0.0, 0.0, 0.0 };
263 HPFLTNB wfl[ 2 ] = { 0.0, 0.0 };
264 HPFLTNB wcl[ 2 ] = { 0.0, 0.0 };
265 HPFLTNB w[ 4 ] = { 0.0, 0.0, 0.0, 0.0 };
266 int16_t index[ 2 ] = { 0, 0 };
267 int32_t finalIdx = 0;
268 int8_t limitX1 = 1; int8_t limitX2 = 1;
269 int8_t limitY1 = 1; int8_t limitY2 = 1;
270 int8_t limitZ1 = 1; int8_t limitZ2 = 1;
273 if( ::fabs( r[ 0 ] ) > ::fabs( r[ 1 ] ) )
280 alphaMin = std::max( alphaMin, std::min( alphaX_0, alphaX_1 ) );
281 alphaMax = std::min( alphaMax, std::max( alphaX_0, alphaX_1 ) );
292 alphaMin = std::max( alphaMin, std::min( alphaY_0, alphaY_1 ) );
293 alphaMax = std::min( alphaMax, std::max( alphaY_0, alphaY_1 ) );
305 alphaMin = std::max( alphaMin, std::min( alphaZ_0, alphaZ_1 ) );
306 alphaMax = std::min( alphaMax, std::max( alphaZ_0, alphaZ_1 ) );
309 if( alphaMax <= alphaMin )
return 0;
311 if( r[ 1 ] == 0.0 )
if( event1[ 1 ] < -
mp_halfFOV[ 1 ] || event1[ 1 ] >
mp_halfFOV[ 1 ] )
return 0;
312 if( r[ 2 ] == 0.0 )
if( event1[ 2 ] < -
mp_halfFOV[ 2 ] || event1[ 2 ] >
mp_halfFOV[ 2 ] )
return 0;
315 HPFLTNB const factor( ::fabs( r[ 0 ] )
316 / ::sqrt( r2[ 0 ] + r2[ 1 ] + r2[ 2 ] ) );
327 int iMin = 0, iMax = 0;
333 else if( r[ 0 ] < 0.0 )
343 for(
int i = iMin; i < iMax; ++i )
347 pos[ 1 ] = event1[ 1 ] + step * ri[ 1 ];
348 pos[ 2 ] = event1[ 2 ] + step * ri[ 2 ];
355 finalIdx = i + ( index[ 0 ] - 1 ) *
mp_nbVox[ 0 ] + ( index[ 1 ] - 1 ) *
m_nbVoxXY;
358 wfl[ 0 ] = pos[ 1 ] - (
m_boundY + index[ 0 ] * mp_sizeVox[ 1 ] );
359 wfl[ 1 ] = pos[ 2 ] - (
m_boundZ + index[ 1 ] * mp_sizeVox[ 2 ] );
360 wfl[ 0 ] /= mp_sizeVox[ 1 ];
361 wfl[ 1 ] /= mp_sizeVox[ 2 ];
364 wcl[ 0 ] = 1.0 - wfl[ 0 ];
365 wcl[ 1 ] = 1.0 - wfl[ 1 ];
368 w[ 0 ] = wcl[ 0 ] * wcl[ 1 ];
369 w[ 1 ] = wcl[ 0 ] * wfl[ 1 ];
370 w[ 2 ] = wfl[ 0 ] * wfl[ 1 ];
371 w[ 3 ] = wfl[ 0 ] * wcl[ 1 ];
374 if( index[ 0 ] <= 0 ) limitY1 = 0;
375 if( index[ 0 ] >=
mp_nbVox[ 1 ] ) limitY2 = 0;
378 if( index[ 1 ] <= 0 ) limitZ1 = 0;
379 if( index[ 1 ] >=
mp_nbVox[ 2 ] ) limitZ2 = 0;
383 ap_ProjectionLine->
AddVoxel(a_direction, finalIdx * limitY1 * limitZ1, w[ 0 ] * weight * limitY1 * limitZ1);
384 ap_ProjectionLine->
AddVoxel(a_direction, ( finalIdx +
m_nbVoxXY ) * limitY1 * limitZ2, w[ 1 ] * weight * limitY1 * limitZ2);
385 ap_ProjectionLine->
AddVoxel(a_direction, ( finalIdx +
mp_nbVox[ 0 ] +
m_nbVoxXY ) * limitY2 * limitZ2, w[ 2 ] * weight * limitY2 * limitZ2);
386 ap_ProjectionLine->
AddVoxel(a_direction, ( finalIdx +
mp_nbVox[ 0 ] ) * limitY2 * limitZ1, w[ 3 ] * weight * limitY2 * limitZ1);
388 limitY1 = 1.0; limitY2 = 1.0;
389 limitZ1 = 1.0; limitZ2 = 1.0;
403 alphaMin = std::max( alphaMin, std::min( alphaX_0, alphaX_1 ) );
404 alphaMax = std::min( alphaMax, std::max( alphaX_0, alphaX_1 ) );
412 alphaMin = std::max( alphaMin, std::min( alphaY_0, alphaY_1 ) );
413 alphaMax = std::min( alphaMax, std::max( alphaY_0, alphaY_1 ) );
424 alphaMin = std::max( alphaMin, std::min( alphaZ_0, alphaZ_1 ) );
425 alphaMax = std::min( alphaMax, std::max( alphaZ_0, alphaZ_1 ) );
428 if( alphaMax <= alphaMin )
return 0;
430 if( r[ 0 ] == 0.0 )
if( event1[ 0 ] < -
mp_halfFOV[ 0 ] || event1[ 0 ] >
mp_halfFOV[ 0 ] )
return 0;
431 if( r[ 2 ] == 0.0 )
if( event1[ 2 ] < -
mp_halfFOV[ 2 ] || event1[ 2 ] >
mp_halfFOV[ 2 ] )
return 0;
434 HPFLTNB const factor( ::fabs( r[ 1 ] )
435 / ::sqrt( r2[ 0 ] + r2[ 1 ] + r2[ 2 ] ) );
446 int jMin = 0, jMax = 0;
452 else if( r[ 1 ] < 0.0 )
462 for(
int j = jMin; j < jMax; ++j )
466 pos[ 0 ] = event1[ 0 ] + step * ri[ 0 ];
467 pos[ 2 ] = event1[ 2 ] + step * ri[ 2 ];
474 finalIdx = ( index[ 0 ] - 1 ) + j *
mp_nbVox[ 0 ] + ( index[ 1 ] - 1 ) *
m_nbVoxXY;
477 wfl[ 0 ] = pos[ 0 ] - (
m_boundX + index[ 0 ] * mp_sizeVox[ 0 ] );
478 wfl[ 1 ] = pos[ 2 ] - (
m_boundZ + index[ 1 ] * mp_sizeVox[ 2 ] );
479 wfl[ 0 ] /= mp_sizeVox[ 0 ];
480 wfl[ 1 ] /= mp_sizeVox[ 2 ];
483 wcl[ 0 ] = 1.0 - wfl[ 0 ];
484 wcl[ 1 ] = 1.0 - wfl[ 1 ];
487 w[ 0 ] = wcl[ 0 ] * wcl[ 1 ];
488 w[ 1 ] = wcl[ 0 ] * wfl[ 1 ];
489 w[ 2 ] = wfl[ 0 ] * wfl[ 1 ];
490 w[ 3 ] = wfl[ 0 ] * wcl[ 1 ];
493 if( index[ 0 ] <= 0 ) limitX1 = 0;
494 if( index[ 0 ] >=
mp_nbVox[ 0 ] ) limitX2 = 0;
497 if( index[ 1 ] <= 0 ) limitZ1 = 0;
498 if( index[ 1 ] >=
mp_nbVox[ 2 ] ) limitZ2 = 0;
502 ap_ProjectionLine->
AddVoxel(a_direction, finalIdx * limitX1 * limitZ1, w[ 0 ] * weight * limitX1 * limitZ1);
503 ap_ProjectionLine->
AddVoxel(a_direction, ( finalIdx +
m_nbVoxXY ) * limitX1 * limitZ2, w[ 1 ] * weight * limitX1 * limitZ2);
504 ap_ProjectionLine->
AddVoxel(a_direction, ( finalIdx + 1 +
m_nbVoxXY ) * limitX2 * limitZ2, w[ 2 ] * weight * limitX2 * limitZ2);
505 ap_ProjectionLine->
AddVoxel(a_direction, ( finalIdx + 1 ) * limitX2 * limitZ1, w[ 3 ] * weight * limitX2 * limitZ1);
508 limitX1 = 1; limitX2 = 1;
509 limitZ1 = 1; limitZ2 = 1;
527 Cerr(
"***** iProjectorJoseph::ProjectWithTOFPos() -> Called while not initialized !" << endl);
532 #ifdef CASTOR_VERBOSE
535 string direction =
"";
536 if (a_direction==
FORWARD) direction =
"forward";
537 else direction =
"backward";
538 Cout(
"iProjectorJoseph::Project with TOF measurement -> Project line '" << ap_ProjectionLine <<
"' in " << direction <<
" direction" << endl);
548 event2[ 0 ] - event1[ 0 ],
549 event2[ 1 ] - event1[ 1 ],
550 event2[ 2 ] - event1[ 2 ]
571 HPFLTNB tof_sigma_sqrt2 = sqrt(2.)*tof_sigma;
578 HPFLTNB lor_tof_center = lor_length * 0.5 + tof_delta;
581 HPFLTNB tof_edge_low[] = {0,0,0};
583 HPFLTNB tof_edge_high[] = {0,0,0};
588 for (
int ax=0;ax<3;ax++)
591 tof_center = event1[ax] + lor_tof_center * r[ax] / lor_length;
594 tof_edge_low[ax] = tof_center - tof_half_span * fabs(r[ax]) / lor_length;
597 if (tof_index>
mp_nbVox[ax]-1)
return 0;
601 tof_edge_high[ax] = tof_center + tof_half_span * fabs(r[ax]) / lor_length;
604 if (tof_index<0)
return 0;
610 HPFLTNB alphaMin = 0.0, alphaMax = 1.0;
613 HPFLTNB pos[ 3 ] = { 0.0, 0.0, 0.0 };
614 HPFLTNB wfl[ 2 ] = { 0.0, 0.0 };
615 HPFLTNB wcl[ 2 ] = { 0.0, 0.0 };
616 HPFLTNB w[ 4 ] = { 0.0, 0.0, 0.0, 0.0 };
617 int16_t index[ 2 ] = { 0, 0 };
618 int32_t finalIdx = 0;
619 int8_t limitX1 = 1; int8_t limitX2 = 1;
620 int8_t limitY1 = 1; int8_t limitY2 = 1;
621 int8_t limitZ1 = 1; int8_t limitZ2 = 1;
624 if( ::fabs( r[ 0 ] ) > ::fabs( r[ 1 ] ) )
629 HPFLTNB const alphaX_0 = ( tof_edge_low[ 0 ] - event1[ 0 ] ) / r[ 0 ];
630 HPFLTNB const alphaX_1 = ( tof_edge_high[ 0 ] - event1[ 0 ] ) / r[ 0 ];
631 alphaMin = std::max( alphaMin, std::min( alphaX_0, alphaX_1 ) );
632 alphaMax = std::min( alphaMax, std::max( alphaX_0, alphaX_1 ) );
639 HPFLTNB const alphaY_0 = ( tof_edge_low[ 1 ] -
mp_sizeVox[ 1 ] * 0.5 - event1[ 1 ] )
641 HPFLTNB const alphaY_1 = ( tof_edge_high[ 1 ] +
mp_sizeVox[ 1 ] * 0.5 - event1[ 1 ] )
643 alphaMin = std::max( alphaMin, std::min( alphaY_0, alphaY_1 ) );
644 alphaMax = std::min( alphaMax, std::max( alphaY_0, alphaY_1 ) );
652 HPFLTNB const alphaZ_0 = ( tof_edge_low[ 2 ] -
mp_sizeVox[ 2 ] * 0.5 - event1[ 2 ] )
654 HPFLTNB const alphaZ_1 = ( tof_edge_high[ 2 ] +
mp_sizeVox[ 2 ] * 0.5 - event1[ 2 ] )
656 alphaMin = std::max( alphaMin, std::min( alphaZ_0, alphaZ_1 ) );
657 alphaMax = std::min( alphaMax, std::max( alphaZ_0, alphaZ_1 ) );
660 if( alphaMax <= alphaMin )
return 0;
662 if( r[ 1 ] == 0.0 )
if( event1[ 1 ] < -
mp_halfFOV[ 1 ] || event1[ 1 ] >
mp_halfFOV[ 1 ] )
return 0;
663 if( r[ 2 ] == 0.0 )
if( event1[ 2 ] < -
mp_halfFOV[ 2 ] || event1[ 2 ] >
mp_halfFOV[ 2 ] )
return 0;
667 HPFLTNB const factor_for_tof( lor_length / r[ 0 ]) ;
678 int iMin = 0, iMax = 0;
684 else if( r[ 0 ] < 0.0 )
694 HPFLTNB previous_edge_erf = erf( ( ( -
mp_halfFOV[ 0 ] + iMin *
mp_sizeVox[ 0 ] - event1[ 0 ] ) * factor_for_tof - lor_tof_center) / tof_sigma_sqrt2 );
695 HPFLTNB next_edge_erf, tof_weight;
698 for(
int i = iMin; i < iMax; ++i )
702 pos[ 1 ] = event1[ 1 ] + step * ri[ 1 ];
703 pos[ 2 ] = event1[ 2 ] + step * ri[ 2 ];
710 wfl[ 0 ] = pos[ 1 ] - (
m_boundY + index[ 0 ] * mp_sizeVox[ 1 ] );
711 wfl[ 1 ] = pos[ 2 ] - (
m_boundZ + index[ 1 ] * mp_sizeVox[ 2 ] );
712 wfl[ 0 ] /= mp_sizeVox[ 1 ];
713 wfl[ 1 ] /= mp_sizeVox[ 2 ];
716 wcl[ 0 ] = 1.0 - wfl[ 0 ];
717 wcl[ 1 ] = 1.0 - wfl[ 1 ];
720 w[ 0 ] = wcl[ 0 ] * wcl[ 1 ];
721 w[ 1 ] = wcl[ 0 ] * wfl[ 1 ];
722 w[ 2 ] = wfl[ 0 ] * wfl[ 1 ];
723 w[ 3 ] = wfl[ 0 ] * wcl[ 1 ];
726 if( index[ 0 ] <= 0 ) limitY1 = 0;
727 if( index[ 0 ] >=
mp_nbVox[ 1 ] ) limitY2 = 0;
730 if( index[ 1 ] <= 0 ) limitZ1 = 0;
731 if( index[ 1 ] >=
mp_nbVox[ 2 ] ) limitZ2 = 0;
734 finalIdx = i + ( index[ 0 ] - 1 ) *
mp_nbVox[ 0 ] + ( index[ 1 ] - 1 ) *
m_nbVoxXY;
737 next_edge_erf = erf( ( ( step + mp_sizeVox[ 0 ] * 0.5 ) * factor_for_tof - lor_tof_center ) / tof_sigma_sqrt2 );
739 tof_weight = 0.5 * ::fabs(previous_edge_erf - next_edge_erf) ;
741 previous_edge_erf = next_edge_erf;
746 ap_ProjectionLine->
AddVoxelInTOFBin(a_direction, 0, finalIdx * limitY1 * limitZ1, w[ 0 ] * tof_weight * limitY1 * limitZ1);
747 ap_ProjectionLine->
AddVoxelInTOFBin(a_direction, 0, ( finalIdx +
m_nbVoxXY ) * limitY1 * limitZ2, w[ 1 ] * tof_weight * limitY1 * limitZ2);
749 ap_ProjectionLine->
AddVoxelInTOFBin(a_direction, 0, ( finalIdx +
mp_nbVox[ 0 ] ) * limitY2 * limitZ1, w[ 3 ] * tof_weight * limitY2 * limitZ1);
752 limitY1 = 1.0; limitY2 = 1.0;
753 limitZ1 = 1.0; limitZ2 = 1.0;
763 HPFLTNB const alphaX_0 = ( tof_edge_low[ 0 ] -
mp_sizeVox[ 0 ] * 0.5 - event1[ 0 ] )
765 HPFLTNB const alphaX_1 = ( tof_edge_high[ 0 ] +
mp_sizeVox[ 0 ] * 0.5 - event1[ 0 ] )
767 alphaMin = std::max( alphaMin, std::min( alphaX_0, alphaX_1 ) );
768 alphaMax = std::min( alphaMax, std::max( alphaX_0, alphaX_1 ) );
774 HPFLTNB const alphaY_0 = ( tof_edge_low[ 1 ] - event1[ 1 ] ) / r[ 1 ];
775 HPFLTNB const alphaY_1 = ( tof_edge_high[ 1 ] - event1[ 1 ] ) / r[ 1 ];
776 alphaMin = std::max( alphaMin, std::min( alphaY_0, alphaY_1 ) );
777 alphaMax = std::min( alphaMax, std::max( alphaY_0, alphaY_1 ) );
784 HPFLTNB const alphaZ_0 = ( tof_edge_low[ 2 ] -
mp_sizeVox[ 2 ] * 0.5 - event1[ 2 ] )
786 HPFLTNB const alphaZ_1 = ( tof_edge_high[ 2 ] +
mp_sizeVox[ 2 ] * 0.5 - event1[ 2 ] )
788 alphaMin = std::max( alphaMin, std::min( alphaZ_0, alphaZ_1 ) );
789 alphaMax = std::min( alphaMax, std::max( alphaZ_0, alphaZ_1 ) );
792 if( alphaMax <= alphaMin )
return 0;
794 if( r[ 0 ] == 0.0 )
if( event1[ 0 ] < -
mp_halfFOV[ 0 ] || event1[ 0 ] >
mp_halfFOV[ 0 ] )
return 0;
795 if( r[ 2 ] == 0.0 )
if( event1[ 2 ] < -
mp_halfFOV[ 2 ] || event1[ 2 ] >
mp_halfFOV[ 2 ] )
return 0;
799 HPFLTNB const factor_for_tof( lor_length / r[ 1 ] );
810 int jMin = 0, jMax = 0;
816 else if( r[ 1 ] < 0.0 )
823 HPFLTNB previous_edge_erf = erf( ( ( -
mp_halfFOV[ 1 ] + jMin *
mp_sizeVox[ 1 ] - event1[ 1 ]) * factor_for_tof - lor_tof_center) / tof_sigma_sqrt2 );
824 HPFLTNB next_edge_erf, tof_weight;
830 for(
int j = jMin; j < jMax; ++j )
834 pos[ 0 ] = event1[ 0 ] + step * ri[ 0 ];
835 pos[ 2 ] = event1[ 2 ] + step * ri[ 2 ];
842 wfl[ 0 ] = pos[ 0 ] - (
m_boundX + index[ 0 ] * mp_sizeVox[ 0 ] );
843 wfl[ 1 ] = pos[ 2 ] - (
m_boundZ + index[ 1 ] * mp_sizeVox[ 2 ] );
844 wfl[ 0 ] /= mp_sizeVox[ 0 ];
845 wfl[ 1 ] /= mp_sizeVox[ 2 ];
848 wcl[ 0 ] = 1.0 - wfl[ 0 ];
849 wcl[ 1 ] = 1.0 - wfl[ 1 ];
852 w[ 0 ] = wcl[ 0 ] * wcl[ 1 ];
853 w[ 1 ] = wcl[ 0 ] * wfl[ 1 ];
854 w[ 2 ] = wfl[ 0 ] * wfl[ 1 ];
855 w[ 3 ] = wfl[ 0 ] * wcl[ 1 ];
858 if( index[ 0 ] <= 0 ) limitX1 = 0;
859 if( index[ 0 ] >=
mp_nbVox[ 0 ] ) limitX2 = 0;
862 if( index[ 1 ] <= 0 ) limitZ1 = 0;
863 if( index[ 1 ] >=
mp_nbVox[ 2 ] ) limitZ2 = 0;
866 finalIdx = ( index[ 0 ] - 1 ) + j *
mp_nbVox[ 0 ] + ( index[ 1 ] - 1 ) *
m_nbVoxXY;
869 next_edge_erf = erf( ( ( step + mp_sizeVox[ 1 ] * 0.5 ) * factor_for_tof - lor_tof_center ) / tof_sigma_sqrt2 );
871 tof_weight = 0.5 * ::fabs(previous_edge_erf - next_edge_erf) ;
873 previous_edge_erf = next_edge_erf;
878 ap_ProjectionLine->
AddVoxelInTOFBin(a_direction, 0, finalIdx * limitX1 * limitZ1, w[ 0 ] * tof_weight * limitX1 * limitZ1);
879 ap_ProjectionLine->
AddVoxelInTOFBin(a_direction, 0, ( finalIdx +
m_nbVoxXY ) * limitX1 * limitZ2, w[ 1 ] * tof_weight * limitX1 * limitZ2);
880 ap_ProjectionLine->
AddVoxelInTOFBin(a_direction, 0, ( finalIdx + 1 +
m_nbVoxXY ) * limitX2 * limitZ2, w[ 2 ] * tof_weight * limitX2 * limitZ2);
881 ap_ProjectionLine->
AddVoxelInTOFBin(a_direction, 0, ( finalIdx + 1 ) * limitX2 * limitZ1, w[ 3 ] * tof_weight * limitX2 * limitZ1);
884 limitX1 = 1; limitX2 = 1;
885 limitZ1 = 1; limitZ2 = 1;
901 Cerr(
"***** iProjectorJoseph::ProjectWithTOFBin() -> Called while not initialized !" << endl);
906 #ifdef CASTOR_VERBOSE
909 string direction =
"";
910 if (a_direction==
FORWARD) direction =
"forward";
911 else direction =
"backward";
912 Cout(
"iProjectorJoseph::Project with TOF bins -> Project line '" << ap_ProjectionLine <<
"' in " << direction <<
" direction" << endl);
922 event2[ 0 ] - event1[ 0 ],
923 event2[ 1 ] - event1[ 1 ],
924 event2[ 2 ] - event1[ 2 ]
929 HPFLTNB lor_length_half = lor_length * 0.5;
937 INTNB tof_half_nb_bins = tof_nb_bins/2;
951 INTNB tof_bin_last = tof_half_nb_bins;
952 INTNB tof_bin_first = -tof_half_nb_bins;
975 HPFLTNB alphaMin = 0.0, alphaMax = 1.0;
978 HPFLTNB pos[ 3 ] = { 0.0, 0.0, 0.0 };
979 HPFLTNB wfl[ 2 ] = { 0.0, 0.0 };
980 HPFLTNB wcl[ 2 ] = { 0.0, 0.0 };
981 HPFLTNB w[ 4 ] = { 0.0, 0.0, 0.0, 0.0 };
982 int16_t index[ 2 ] = { 0, 0 };
983 int32_t finalIdx = 0;
984 int8_t limitX1 = 1; int8_t limitX2 = 1;
985 int8_t limitY1 = 1; int8_t limitY2 = 1;
986 int8_t limitZ1 = 1; int8_t limitZ2 = 1;
989 if( ::fabs( r[ 0 ] ) > ::fabs( r[ 1 ] ) )
996 alphaMin = std::max( alphaMin, std::min( alphaX_0, alphaX_1 ) );
997 alphaMax = std::min( alphaMax, std::max( alphaX_0, alphaX_1 ) );
1008 alphaMin = std::max( alphaMin, std::min( alphaY_0, alphaY_1 ) );
1009 alphaMax = std::min( alphaMax, std::max( alphaY_0, alphaY_1 ) );
1021 alphaMin = std::max( alphaMin, std::min( alphaZ_0, alphaZ_1 ) );
1022 alphaMax = std::min( alphaMax, std::max( alphaZ_0, alphaZ_1 ) );
1025 if( alphaMax <= alphaMin )
return 0;
1027 if( r[ 1 ] == 0.0 )
if( event1[ 1 ] < -
mp_halfFOV[ 1 ] || event1[ 1 ] >
mp_halfFOV[ 1 ] )
return 0;
1028 if( r[ 2 ] == 0.0 )
if( event1[ 2 ] < -
mp_halfFOV[ 2 ] || event1[ 2 ] >
mp_halfFOV[ 2 ] )
return 0;
1033 for (
INTNB tof_bin=0; tof_bin<tof_nb_bins; tof_bin++) tof_weights_temp[tof_bin] = 0.;
1036 HPFLTNB const factor( ::fabs( r[ 0 ] ) / lor_length );
1037 HPFLTNB const factor_for_tof( lor_length / r[ 0 ] );
1048 int iMin = 0, iMax = 0;
1054 else if( r[ 0 ] < 0.0 )
1064 for(
int i = iMin; i < iMax; ++i )
1068 pos[ 1 ] = event1[ 1 ] + step * ri[ 1 ];
1069 pos[ 2 ] = event1[ 2 ] + step * ri[ 2 ];
1075 finalIdx = i + ( index[ 0 ] - 1 ) *
mp_nbVox[ 0 ] + ( index[ 1 ] - 1 ) *
m_nbVoxXY;
1081 INTNB tof_bin_first_for_voxel = max(tof_bin_first , (
INTNB)(trunc( (step * factor_for_tof - tof_half_span - lor_length_half ) / tof_bin_size )));
1082 INTNB tof_bin_last_for_voxel = min(tof_bin_last , (
INTNB)(trunc( (step * factor_for_tof + tof_half_span - lor_length_half ) / tof_bin_size )));
1083 lor_tof_center = lor_length_half + tof_bin_first_for_voxel * tof_bin_size;
1086 if(tof_bin_first_for_voxel>tof_bin_last || tof_bin_last_for_voxel<tof_bin_first)
continue;
1089 tof_bin_first_for_voxel += tof_half_nb_bins;
1090 tof_bin_last_for_voxel += tof_half_nb_bins;
1094 for (
INTNB tof_bin=tof_bin_first_for_voxel; tof_bin<=tof_bin_last_for_voxel; tof_bin++)
1098 HPFLTNB temp = ( step * factor_for_tof - lor_tof_center) / tof_sigma;
1099 tof_weight = exp(- 0.5 * temp * temp ) * gaussian_norm_coef * weight;
1101 tof_norm_coef += tof_weight;
1103 tof_weights_temp[tof_bin] = tof_weight;
1105 lor_tof_center += tof_bin_size;
1109 wfl[ 0 ] = pos[ 1 ] - (
m_boundY + index[ 0 ] * mp_sizeVox[ 1 ] );
1110 wfl[ 1 ] = pos[ 2 ] - (
m_boundZ + index[ 1 ] * mp_sizeVox[ 2 ] );
1111 wfl[ 0 ] /= mp_sizeVox[ 1 ];
1112 wfl[ 1 ] /= mp_sizeVox[ 2 ];
1115 wcl[ 0 ] = 1.0 - wfl[ 0 ];
1116 wcl[ 1 ] = 1.0 - wfl[ 1 ];
1119 w[ 0 ] = wcl[ 0 ] * wcl[ 1 ];
1120 w[ 1 ] = wcl[ 0 ] * wfl[ 1 ];
1121 w[ 2 ] = wfl[ 0 ] * wfl[ 1 ];
1122 w[ 3 ] = wfl[ 0 ] * wcl[ 1 ];
1125 if( index[ 0 ] <= 0 ) limitY1 = 0;
1126 if( index[ 0 ] >=
mp_nbVox[ 1 ] ) limitY2 = 0;
1129 if( index[ 1 ] <= 0 ) limitZ1 = 0;
1130 if( index[ 1 ] >=
mp_nbVox[ 2 ] ) limitZ2 = 0;
1133 if (tof_norm_coef>0.)
1136 for (
INTNB tof_bin=tof_bin_first_for_voxel; tof_bin<=tof_bin_last_for_voxel; tof_bin++)
1138 tof_weights_temp[tof_bin] /= tof_norm_coef;
1141 ap_ProjectionLine->
AddVoxelAllTOFBins(a_direction, finalIdx * limitY1 * limitZ1, w[ 0 ] * weight * limitY1 * limitZ1, tof_weights_temp, tof_bin_first_for_voxel, tof_bin_last_for_voxel);
1142 ap_ProjectionLine->
AddVoxelAllTOFBins(a_direction, ( finalIdx +
m_nbVoxXY ) * limitY1 * limitZ2, w[ 1 ] * weight * limitY1 * limitZ2 , tof_weights_temp, tof_bin_first_for_voxel, tof_bin_last_for_voxel);
1143 ap_ProjectionLine->
AddVoxelAllTOFBins(a_direction, ( finalIdx +
mp_nbVox[ 0 ] +
m_nbVoxXY ) * limitY2 * limitZ2, w[ 2 ] * weight * limitY2 * limitZ2 , tof_weights_temp, tof_bin_first_for_voxel, tof_bin_last_for_voxel);
1144 ap_ProjectionLine->
AddVoxelAllTOFBins(a_direction, ( finalIdx +
mp_nbVox[ 0 ] ) * limitY2 * limitZ1, w[ 3 ] * weight * limitY2 * limitZ1 , tof_weights_temp, tof_bin_first_for_voxel, tof_bin_last_for_voxel);
1147 limitY1 = 1.0; limitY2 = 1.0;
1148 limitZ1 = 1.0; limitZ2 = 1.0;
1150 delete[] tof_weights_temp;
1163 alphaMin = std::max( alphaMin, std::min( alphaX_0, alphaX_1 ) );
1164 alphaMax = std::min( alphaMax, std::max( alphaX_0, alphaX_1 ) );
1172 alphaMin = std::max( alphaMin, std::min( alphaY_0, alphaY_1 ) );
1173 alphaMax = std::min( alphaMax, std::max( alphaY_0, alphaY_1 ) );
1184 alphaMin = std::max( alphaMin, std::min( alphaZ_0, alphaZ_1 ) );
1185 alphaMax = std::min( alphaMax, std::max( alphaZ_0, alphaZ_1 ) );
1188 if( alphaMax <= alphaMin )
return 0;
1190 if( r[ 0 ] == 0.0 )
if( event1[ 0 ] < -
mp_halfFOV[ 0 ] || event1[ 0 ] >
mp_halfFOV[ 0 ] )
return 0;
1191 if( r[ 2 ] == 0.0 )
if( event1[ 2 ] < -
mp_halfFOV[ 2 ] || event1[ 2 ] >
mp_halfFOV[ 2 ] )
return 0;
1195 for (
INTNB tof_bin=0; tof_bin<tof_nb_bins; tof_bin++) tof_weights_temp[tof_bin] = 0.;
1198 HPFLTNB const factor( ::fabs( r[ 1 ] ) / lor_length );
1199 HPFLTNB const factor_for_tof( lor_length / r[ 1 ] );
1210 int jMin = 0, jMax = 0;
1216 else if( r[ 1 ] < 0.0 )
1226 for(
int j = jMin; j < jMax; ++j )
1230 pos[ 0 ] = event1[ 0 ] + step * ri[ 0 ];
1231 pos[ 2 ] = event1[ 2 ] + step * ri[ 2 ];
1237 finalIdx = ( index[ 0 ] - 1 ) + j *
mp_nbVox[ 0 ] + ( index[ 1 ] - 1 ) *
m_nbVoxXY;
1243 INTNB tof_bin_first_for_voxel = max(tof_bin_first , (
INTNB)(trunc( (step * factor_for_tof - tof_half_span - lor_length_half ) / tof_bin_size )));
1244 INTNB tof_bin_last_for_voxel = min(tof_bin_last , (
INTNB)(trunc( (step * factor_for_tof + tof_half_span - lor_length_half ) / tof_bin_size )));
1245 lor_tof_center = lor_length_half + tof_bin_first_for_voxel * tof_bin_size;
1248 if(tof_bin_first_for_voxel>tof_bin_last || tof_bin_last_for_voxel<tof_bin_first)
continue;
1251 tof_bin_first_for_voxel += tof_half_nb_bins;
1252 tof_bin_last_for_voxel += tof_half_nb_bins;
1256 for (
INTNB tof_bin=tof_bin_first_for_voxel; tof_bin<=tof_bin_last_for_voxel; tof_bin++)
1260 HPFLTNB temp = ( step * factor_for_tof - lor_tof_center) / tof_sigma;
1261 tof_weight = exp(- 0.5 * temp * temp ) * gaussian_norm_coef * weight;
1263 tof_norm_coef += tof_weight;
1265 tof_weights_temp[tof_bin] = tof_weight;
1267 lor_tof_center += tof_bin_size;
1271 wfl[ 0 ] = pos[ 0 ] - (
m_boundX + index[ 0 ] * mp_sizeVox[ 0 ] );
1272 wfl[ 1 ] = pos[ 2 ] - (
m_boundZ + index[ 1 ] * mp_sizeVox[ 2 ] );
1273 wfl[ 0 ] /= mp_sizeVox[ 0 ];
1274 wfl[ 1 ] /= mp_sizeVox[ 2 ];
1277 wcl[ 0 ] = 1.0 - wfl[ 0 ];
1278 wcl[ 1 ] = 1.0 - wfl[ 1 ];
1281 w[ 0 ] = wcl[ 0 ] * wcl[ 1 ];
1282 w[ 1 ] = wcl[ 0 ] * wfl[ 1 ];
1283 w[ 2 ] = wfl[ 0 ] * wfl[ 1 ];
1284 w[ 3 ] = wfl[ 0 ] * wcl[ 1 ];
1287 if( index[ 0 ] <= 0 ) limitX1 = 0;
1288 if( index[ 0 ] >=
mp_nbVox[ 0 ] ) limitX2 = 0;
1291 if( index[ 1 ] <= 0 ) limitZ1 = 0;
1292 if( index[ 1 ] >=
mp_nbVox[ 2 ] ) limitZ2 = 0;
1297 if (tof_norm_coef>0.)
1300 for (
INTNB tof_bin=tof_bin_first_for_voxel; tof_bin<=tof_bin_last_for_voxel; tof_bin++)
1302 tof_weights_temp[tof_bin] /= tof_norm_coef;
1305 ap_ProjectionLine->
AddVoxelAllTOFBins(a_direction, finalIdx * limitX1 * limitZ1, w[ 0 ] * weight * limitX1 * limitZ1, tof_weights_temp, tof_bin_first_for_voxel, tof_bin_last_for_voxel);
1306 ap_ProjectionLine->
AddVoxelAllTOFBins(a_direction, ( finalIdx +
m_nbVoxXY ) * limitX1 * limitZ2, w[ 1 ] * weight * limitX1 * limitZ2, tof_weights_temp, tof_bin_first_for_voxel, tof_bin_last_for_voxel);
1307 ap_ProjectionLine->
AddVoxelAllTOFBins(a_direction, ( finalIdx + 1 +
m_nbVoxXY ) * limitX2 * limitZ2, w[ 2 ] * weight * limitX2 * limitZ2, tof_weights_temp, tof_bin_first_for_voxel, tof_bin_last_for_voxel);
1308 ap_ProjectionLine->
AddVoxelAllTOFBins(a_direction, ( finalIdx + 1 ) * limitX2 * limitZ1, w[ 3 ] * weight * limitX2 * limitZ1, tof_weights_temp, tof_bin_first_for_voxel, tof_bin_last_for_voxel);
1311 limitX1 = 1; limitX2 = 1;
1312 limitZ1 = 1; limitZ2 = 1;
1314 delete[] tof_weights_temp;
bool m_compatibleWithSPECTAttenuationCorrection
int InitializeSpecific()
This function is used to initialize specific stuff to the child projector.
void ShowHelpSpecific()
A function used to show help about the child module.
void AddVoxelAllTOFBins(int a_direction, INTNB a_voxelIndex, FLTNB a_voxelWeight, HPFLTNB *a_tofWeights, INTNB a_tofBinFirst, INTNB a_tofBinLast)
Add a voxel contribution to the line for all relevant TOF bins.
int ProjectWithTOFPos(int a_direction, oProjectionLine *ap_ProjectionLine)
A function to project with TOF continuous information.
#define TWO_SQRT_TWO_LN_2
oImageDimensionsAndQuantification * mp_ImageDimensionsAndQuantification
This class is designed to generically described any on-the-fly projector.
int ProjectWithTOFBin(int a_direction, oProjectionLine *ap_ProjectionLine)
A function to project with TOF binned information.
int ReadConfigurationFile(const string &a_configurationFile)
A function used to read options from a configuration file.
FLTNB GetTOFMeasurement()
This function is used to get the TOF measurement.
FLTNB GetLength()
This function is used to get the length of the line.
int ReadOptionsList(const string &a_optionsList)
A function used to read options from a list of options.
int CheckSpecificParameters()
A private function used to check the parameters settings specific to the child projector.
~iProjectorJoseph()
The destructor of iProjectorJoseph.
FLTNB GetTOFResolution()
This function is used to get the TOF resolution.
FLTNB * GetPosition1()
This function is used to get the pointer to the mp_position1 (3-values tab).
void AddVoxel(int a_direction, INTNB a_voxelIndice, FLTNB a_voxelWeight)
This function is used to add a voxel contribution to the line, assuming TOF bin 0 (i...
INTNB EstimateMaxNumberOfVoxelsPerLine()
This function is used to compute and provide an estimate of the maximum number of voxels that could c...
Declaration of class iProjectorJoseph.
This class is designed to manage and store system matrix elements associated to a vEvent...
int ProjectWithoutTOF(int a_direction, oProjectionLine *ap_ProjectionLine)
A function to project without TOF.
Declaration of class sOutputManager.
int GetNbTOFBins()
This function is used to get the number of TOF bins in use.
FLTNB * GetPosition2()
This function is used to get the pointer to the mp_position2 (3-values tab).
INTNB GetNbVoxX()
Get the number of voxels along the X axis.
FLTNB GetTOFBinSize()
This function is used to get the size in ps of a TOF bin.
INTNB GetNbVoxZ()
Get the number of voxels along the Z axis.
iProjectorJoseph()
The constructor of iProjectorJoseph.
bool m_compatibleWithCompression
void AddVoxelInTOFBin(int a_direction, int a_TOFBin, INTNB a_voxelIndice, FLTNB a_voxelWeight)
This function is used to add a voxel contribution to the line and provided TOF bin.
INTNB GetNbVoxY()
Get the number of voxels along the Y axis.