8 #include "iProjectorDistanceDriven.hh" 9 #include "sOutputManager.hh" 75 if (
ReadStringOption(a_optionsList, option, 1,
",",
"Tolerance factor for plane index computation "))
77 Cerr(
"***** iProjectorDistanceDriven::ReadConfigurationFile() -> Failed to correctly read the list of options !" << endl);
84 Cerr(
"***** iProjectorDistanceDriven::ReadOptionsList() -> Tolerance factor parameter must be >2 (tolerance factor < 10^-2)" << endl);
85 Cerr(
" -> Provided parameter: "<< option[0] << endl);
102 cout <<
"This projector is a line projector based on computations of overlap between a pair of detection elements and voxels." << endl;
103 cout <<
"It is implemented from the following published paper:" << endl;
104 cout <<
"B. De Man and S. Basu, \"Distance-driven projection and backprojection in three dimensions\", Phys. Med. Biol., vol. 49, pp. 2463-75, 2004." << endl;
105 cout <<
"There is 1 optional parameter for this projector:" << endl;
106 cout <<
" tolerance_factor: x. -> 'x' must be an unsigned integer, and represent the tolerance precision factor for plane index computation (10^(-x))." << endl;
107 cout <<
" -> Default: 'x' = 6" << endl;
120 Cerr(
"***** iProjectorDistanceDriven::CheckSpecificParameters() -> Tolerance factor must be defined in the specific interval : ]0 ; 1.e-2]" << endl);
121 Cerr(
"***** -> Default value is 1.e-6" << endl);
138 if (
m_verbose>=2)
Cout(
"iProjectorDistanceDriven::InitializeSpecific() -> Use Distance Driven projector" << endl);
170 Cerr(
"***** iProjectorDistanceDriven::ProjectWithoutTOF() -> Called while not initialized !" << endl);
175 #ifdef CASTOR_VERBOSE 178 string direction =
"";
179 if (a_direction==
FORWARD) direction =
"forward";
180 else direction =
"backward";
181 Cout(
"iProjectorDistanceDriven::Project without TOF -> Project line '" << ap_ProjectionLine <<
"' in " << direction <<
" direction" << endl);
239 &p1_x[1], &p1_y[1], &p1_z[1],
240 &p2_x[1], &p2_y[1], &p2_z[1]
243 Cerr(
"***** iProjectorDistanceDriven::ProjectWithoutTOF() -> A problem occurred while getting the edges' center positions !" << endl);
254 p1_x[ 0 ] = p1[ 0 ]; p1_y[ 0 ] = p1[ 1 ]; p1_z[ 0 ] = p1[ 2 ];
257 p2_x[ 0 ] = p2[ 0 ]; p2_y[ 0 ] = p2[ 1 ]; p2_z[ 0 ] = p2[ 2 ];
266 for(
int p = 0; p < 5; ++p )
268 r[ p ][ 0 ] = p2_x[ p ] - p1_x[ p ];
269 r[ p ][ 1 ] = p2_y[ p ] - p1_y[ p ];
270 r[ p ][ 2 ] = p2_z[ p ] - p1_z[ p ];
275 r[ 0 ][ 0 ] * r[ 0 ][ 0 ],
276 r[ 0 ][ 1 ] * r[ 0 ][ 1 ],
277 r[ 0 ][ 2 ] * r[ 0 ][ 2 ]
282 HPFLTNB alpha_min = 0.0, alpha_max = 1.0;
286 HPFLTNB alpha_x_min[ 4 ], alpha_x_max[ 4 ];
287 HPFLTNB alpha_y_min[ 4 ], alpha_y_max[ 4 ];
288 HPFLTNB alpha_z_min[ 4 ], alpha_z_max[ 4 ];
313 float const angle = std::acos( ( r[ 0 ][ 0 ] ) / ( std::sqrt( r2[ 0 ] + r2[ 1 ] ) ) ) * 180.0f / M_PI;
316 if( ( angle >= 0.0 && angle <= 45.0 ) || ( angle >= 135.0 && angle <= 180.0 ) )
320 alpha_x_min[ 0 ] = ( (-
mp_halfFOV[ 0 ]) - p1_x[ 0 ] ) / r[ 0 ][ 0 ];
321 alpha_x_min[ 1 ] = (
mp_halfFOV[ 0 ] - p1_x[ 0 ] ) / r[ 0 ][ 0 ];
322 alpha_x_max[ 0 ] = alpha_x_min[ 0 ];
323 alpha_x_max[ 1 ] = alpha_x_min[ 1 ];
324 alpha_min = std::max( alpha_min, std::min( alpha_x_min[ 0 ], alpha_x_min[ 1 ] ) );
325 alpha_max = std::min( alpha_max, std::max( alpha_x_max[ 0 ], alpha_x_max[ 1 ] ) );
329 if( r[ 1 ][ 1 ] != 0.0 )
331 alpha_y_min[ 0 ] = ( (-
mp_halfFOV[ 1 ]) - p1_y[ 1 ] ) / r[ 1 ][ 1 ];
332 alpha_y_min[ 1 ] = (
mp_halfFOV[ 1 ] - p1_y[ 1 ] ) / r[ 1 ][ 1 ];
333 alpha_y_max[ 0 ] = alpha_y_min[ 0 ];
334 alpha_y_max[ 1 ] = alpha_y_min[ 1 ];
338 alpha_y_min[ 0 ] = 0.0;
339 alpha_y_min[ 1 ] = 0.0;
340 alpha_y_max[ 0 ] = 1.0;
341 alpha_y_max[ 1 ] = 1.0;
344 if( r[ 2 ][ 1 ] != 0.0 )
346 alpha_y_min[ 2 ] = ( (-
mp_halfFOV[ 1 ]) - p1_y[ 2 ] ) / r[ 2 ][ 1 ];
347 alpha_y_min[ 3 ] = (
mp_halfFOV[ 1 ] - p1_y[ 2 ] ) / r[ 2 ][ 1 ];
348 alpha_y_max[ 2 ] = alpha_y_min[ 2 ];
349 alpha_y_max[ 3 ] = alpha_y_min[ 3 ];
353 alpha_y_min[ 2 ] = 0.0;
354 alpha_y_min[ 3 ] = 0.0;
355 alpha_y_max[ 2 ] = 1.0;
356 alpha_y_max[ 3 ] = 1.0;
360 alpha_min = std::max( alpha_min,
361 alpha_y_min[ std::minmax_element( alpha_y_min, alpha_y_min + 4 ).first - alpha_y_min ] );
363 alpha_max = std::min( alpha_max,
364 alpha_y_max[ std::minmax_element( alpha_y_max, alpha_y_max + 4 ).second - alpha_y_max ] );
367 if( r[ 3 ][ 2 ] != 0.0 )
369 alpha_z_min[ 0 ] = ( (-
mp_halfFOV[ 2 ]) - p1_z[ 3 ] ) / r[ 3 ][ 2 ];
370 alpha_z_min[ 1 ] = (
mp_halfFOV[ 2 ] - p1_z[ 3 ] ) / r[ 3 ][ 2 ];
371 alpha_z_max[ 0 ] = alpha_z_min[ 0 ];
372 alpha_z_max[ 1 ] = alpha_z_min[ 1 ];
376 alpha_z_min[ 0 ] = 0.0;
377 alpha_z_min[ 1 ] = 0.0;
378 alpha_z_max[ 0 ] = 1.0;
379 alpha_z_max[ 1 ] = 1.0;
382 if( r[ 4 ][ 2 ] != 0.0 )
384 alpha_z_min[ 2 ] = ( (-
mp_halfFOV[ 2 ]) - p1_z[ 4 ] ) / r[ 4 ][ 2 ];
385 alpha_z_min[ 3 ] = (
mp_halfFOV[ 2 ] - p1_z[ 4 ] ) / r[ 4 ][ 2 ];
386 alpha_z_max[ 2 ] = alpha_z_min[ 2 ];
387 alpha_z_max[ 3 ] = alpha_z_min[ 3 ];
391 alpha_z_min[ 2 ] = 0.0;
392 alpha_z_min[ 3 ] = 0.0;
393 alpha_z_max[ 2 ] = 1.0;
394 alpha_z_max[ 3 ] = 1.0;
398 alpha_min = std::max( alpha_min,
399 alpha_z_min[ std::minmax_element( alpha_z_min, alpha_z_min + 4 ).first
402 alpha_max = std::min( alpha_max,
403 alpha_z_max[ std::minmax_element( alpha_z_max, alpha_z_max + 4 ).second
406 if( alpha_max <= alpha_min )
return 0;
409 int16_t i_min = 0, i_max = 0;
410 if( r[ 0 ][ 0 ] > 0.0 )
415 else if( r[ 0 ][ 0 ] < 0.0 )
423 HPFLTNB const factor( ::fabs( r[ 0 ][ 0 ] ) / ::sqrt( r2[ 0 ] + r2[ 1 ] + r2[ 2 ] ) );
428 for( uint8_t p = 0; p < 4; ++p )
431 ri[ p ][ 1 ] = r[ p + 1 ][ 1 ] / r[ p + 1 ][ 0 ];
432 ri[ p ][ 2 ] = r[ p + 1 ][ 2 ] / r[ p + 1 ][ 0 ];
436 int8_t incr_orient_trans = 0;
437 int8_t idx_orient_trans = 0;
440 int8_t
const incr_orient_axial = p2_z[ 3 ] < p2_z[ 4 ] ? 1 : -1;
444 int8_t
const idx_orient_axial = p2_z[ 3 ] < p2_z[ 4 ] ? 1 : 0;
450 for( int16_t i = i_min; i < i_max; ++i )
455 pos[ 0 ] = p1_y[ 1 ] + step * ri[ 0 ][ 1 ];
456 pos[ 1 ] = p1_y[ 2 ] + step * ri[ 1 ][ 1 ];
458 pos[ 2 ] = p1_z[ 3 ] + step * ri[ 2 ][ 2 ];
459 pos[ 3 ] = p1_z[ 4 ] + step * ri[ 3 ][ 2 ];
462 w1 = ::fabs( pos[ 0 ] - pos[ 1 ] );
463 w2 = ::fabs( pos[ 2 ] - pos[ 3 ] );
465 if( ( w1 * w2 ) != 0 ) final_weight = weight / ( w1 * w2 );
478 bool test_index = (index[ 0 ] >= 0 && index[ 2 ] >= 0 && index[ 1 ] >= 0 && index[ 3 ] >= 0
482 if( index[ 0 ] < index[ 1 ] )
484 incr_orient_trans = 1;
485 idx_orient_trans = 1;
487 else if( index[ 0 ] > index[ 1 ] )
489 incr_orient_trans = -1;
490 idx_orient_trans = 0;
494 int16_t
const n_distance_y = ::abs( index[ 0 ] - index[ 1 ] ) + 2;
496 distance_y[ 0 ] = pos[ 0 ];
497 distance_y[ n_distance_y - 1 ] = pos[ 1 ];
499 if( n_distance_y > 2 )
501 for( int16_t d = 0; d < n_distance_y - 2; ++d )
502 distance_y[ d + 1 ] = (-
mp_halfFOV[ 1 ]) + ( index[ 0 ] + idx_orient_trans + ( incr_orient_trans * d ) ) * mp_sizeVox[ 1 ];
506 for( int16_t d = 0; d < n_distance_y - 1; ++d )
507 distance_y[ d ] = ::fabs( distance_y[ d + 1 ] - distance_y[ d ] );
510 int16_t
const n_distance_z = ::abs( index[ 2 ] - index[ 3 ] ) + 2;
512 distance_z[ 0 ] = pos[ 2 ];
513 distance_z[ n_distance_z - 1 ] = pos[ 3 ];
515 if( n_distance_z > 2 )
517 for( int16_t d = 0; d < n_distance_z - 2; ++d )
518 distance_z[ d + 1 ] = (-
mp_halfFOV[ 2 ]) + ( index[ 2 ] + idx_orient_axial + ( incr_orient_axial * d ) ) * mp_sizeVox[ 2 ];
522 for( int16_t d = 0; d < n_distance_z - 1; ++d )
523 distance_z[ d ] = ::fabs( distance_z[ d + 1 ] - distance_z[ d ] );
526 int16_t index_y, index_z;
527 for( int16_t jj = 0; jj < n_distance_z - 1; ++jj )
529 index_z = index[ 2 ] + jj * incr_orient_axial;
530 if( index_z < 0 || index_z >
mp_nbVox[ 2 ] - 1 )
continue;
532 for( int16_t ii = 0; ii < n_distance_y - 1; ++ii )
534 index_y = index[ 0 ] + ii * incr_orient_trans;
535 if( index_y < 0 || index_y >
mp_nbVox[ 1 ] - 1 )
continue;
537 ap_ProjectionLine->
AddVoxel(a_direction, i + index_y *
mp_nbVox[ 0 ] + index_z * m_nbVoxXY, final_weight * distance_z[ jj ] * distance_y[ ii ]);
546 if( r[ 1 ][ 0 ] != 0.0 )
548 alpha_x_min[ 0 ] = ( (-
mp_halfFOV[ 0 ]) - p1_x[ 1 ] ) / r[ 1 ][ 0 ];
549 alpha_x_min[ 1 ] = (
mp_halfFOV[ 0 ] - p1_x[ 1 ] ) / r[ 1 ][ 0 ];
550 alpha_x_max[ 0 ] = alpha_x_min[ 0 ];
551 alpha_x_max[ 1 ] = alpha_x_min[ 1 ];
555 alpha_x_min[ 0 ] = 0.0;
556 alpha_x_min[ 1 ] = 0.0;
557 alpha_x_max[ 0 ] = 1.0;
558 alpha_x_max[ 1 ] = 1.0;
561 if( r[ 2 ][ 0 ] != 0.0 )
563 alpha_x_min[ 2 ] = ( (-
mp_halfFOV[ 0 ]) - p1_x[ 2 ] ) / r[ 2 ][ 0 ];
564 alpha_x_min[ 3 ] = (
mp_halfFOV[ 0 ] - p1_x[ 2 ] ) / r[ 2 ][ 0 ];
565 alpha_x_max[ 2 ] = alpha_x_min[ 2 ];
566 alpha_x_max[ 3 ] = alpha_x_min[ 3 ];
570 alpha_x_min[ 2 ] = 0.0;
571 alpha_x_min[ 3 ] = 0.0;
572 alpha_x_max[ 2 ] = 1.0;
573 alpha_x_max[ 3 ] = 1.0;
577 alpha_min = std::max( alpha_min,
578 alpha_x_min[ std::minmax_element( alpha_x_min, alpha_x_min + 4 ).first - alpha_x_min ] );
580 alpha_max = std::min( alpha_max,
581 alpha_x_max[ std::minmax_element( alpha_x_max, alpha_x_max + 4 ).second - alpha_x_max ] );
585 alpha_y_min[ 0 ] = ( (-
mp_halfFOV[ 1 ]) - p1_y[ 0 ] ) / r[ 0 ][ 1 ];
586 alpha_y_min[ 1 ] = (
mp_halfFOV[ 1 ] - p1_y[ 0 ] ) / r[ 0 ][ 1 ];
587 alpha_y_max[ 0 ] = alpha_y_min[ 0 ];
588 alpha_y_max[ 1 ] = alpha_y_min[ 1 ];
589 alpha_min = std::max( alpha_min,
590 std::min( alpha_y_min[ 0 ], alpha_y_min[ 1 ] ) );
591 alpha_max = std::min( alpha_max,
592 std::max( alpha_y_max[ 0 ], alpha_y_max[ 1 ] ) );
595 if( r[ 3 ][ 2 ] != 0.0 )
597 alpha_z_min[ 0 ] = ( (-
mp_halfFOV[ 2 ]) - p1_z[ 3 ] ) / r[ 3 ][ 2 ];
598 alpha_z_min[ 1 ] = (
mp_halfFOV[ 2 ] - p1_z[ 3 ] ) / r[ 3 ][ 2 ];
599 alpha_z_max[ 0 ] = alpha_z_min[ 0 ];
600 alpha_z_max[ 1 ] = alpha_z_min[ 1 ];
604 alpha_z_min[ 0 ] = 0.0;
605 alpha_z_min[ 1 ] = 0.0;
606 alpha_z_max[ 0 ] = 1.0;
607 alpha_z_max[ 1 ] = 1.0;
610 if( r[ 4 ][ 2 ] != 0.0 )
612 alpha_z_min[ 2 ] = ( (-
mp_halfFOV[ 2 ]) - p1_z[ 4 ] ) / r[ 4 ][ 2 ];
613 alpha_z_min[ 3 ] = (
mp_halfFOV[ 2 ] - p1_z[ 4 ] ) / r[ 4 ][ 2 ];
614 alpha_z_max[ 2 ] = alpha_z_min[ 2 ];
615 alpha_z_max[ 3 ] = alpha_z_min[ 3 ];
619 alpha_z_min[ 2 ] = 0.0;
620 alpha_z_min[ 3 ] = 0.0;
621 alpha_z_max[ 2 ] = 1.0;
622 alpha_z_max[ 3 ] = 1.0;
626 alpha_min = std::max( alpha_min, alpha_z_min[ std::minmax_element( alpha_z_min, alpha_z_min + 4 ).first - alpha_z_min ] );
628 alpha_max = std::min( alpha_max, alpha_z_max[ std::minmax_element( alpha_z_max, alpha_z_max + 4 ).second - alpha_z_max ] );
630 if( alpha_max <= alpha_min )
return 0;
633 int16_t j_min = 0, j_max = 0;
634 if( r[ 0 ][ 1 ] > 0.0 )
637 j_max = ::floor(
m_toleranceY + ( p1_y[ 0 ] + alpha_max * r[ 0 ][ 1 ] - (-
mp_halfFOV[ 1 ]) ) / mp_sizeVox[ 1 ] );
639 else if( r[ 0 ][ 1 ] < 0.0 )
642 j_max = ::floor(
m_toleranceY + ( p1_y[ 0 ] + alpha_min * r[ 0 ][ 1 ] - (-
mp_halfFOV[ 1 ]) ) / mp_sizeVox[ 1 ] );
647 HPFLTNB const factor( ::fabs( r[ 0 ][ 1 ] ) / ::sqrt( r2[ 0 ] + r2[ 1 ] + r2[ 2 ] ) );
648 HPFLTNB weight( mp_sizeVox[ 1 ] / factor );
652 for( uint8_t p = 0; p < 4; ++p )
654 ri[ p ][ 0 ] = r[ p + 1 ][ 0 ] / r[ p + 1 ][ 1 ];
656 ri[ p ][ 2 ] = r[ p + 1 ][ 2 ] / r[ p + 1 ][ 1 ];
660 int8_t incr_orient_trans = 0;
661 int8_t idx_orient_trans = 0;
664 int8_t
const incr_orient_axial = p2_z[ 3 ] < p2_z[ 4 ] ? 1 : -1;
666 int8_t
const idx_orient_axial = p2_z[ 3 ] < p2_z[ 4 ] ? 1 : 0;
669 HPFLTNB const offset = (-
mp_halfFOV[ 1 ]) + ( mp_sizeVox[ 1 ] * 0.5 ) - p1_y[ 0 ];
672 for( int16_t j = j_min; j < j_max; ++j )
675 HPFLTNB const step = offset + j * mp_sizeVox[ 1 ];
677 pos[ 0 ] = p1_x[ 1 ] + step * ri[ 0 ][ 0 ];
678 pos[ 1 ] = p1_x[ 2 ] + step * ri[ 1 ][ 0 ];
680 pos[ 2 ] = p1_z[ 3 ] + step * ri[ 2 ][ 2 ];
681 pos[ 3 ] = p1_z[ 4 ] + step * ri[ 3 ][ 2 ];
684 w1 = ::fabs( pos[ 0 ] - pos[ 1 ] );
685 w2 = ::fabs( pos[ 2 ] - pos[ 3 ] );
687 if( ( w1 * w2 ) != 0 ) final_weight = weight / ( w1 * w2 );
700 bool test_index = (index[ 0 ] >= 0 && index[ 2 ] >= 0 && index[ 1 ] >= 0 && index[ 3 ] >= 0
704 if( index[ 0 ] < index[ 1 ] )
706 incr_orient_trans = 1;
707 idx_orient_trans = 1;
709 else if( index[ 0 ] > index[ 1 ] )
711 incr_orient_trans = -1;
712 idx_orient_trans = 0;
716 int16_t
const n_distance_x = ::abs( index[ 0 ] - index[ 1 ] ) + 2;
718 distance_x[ 0 ] = pos[ 0 ];
719 distance_x[ n_distance_x - 1 ] = pos[ 1 ];
721 if( n_distance_x > 2 )
723 for( int16_t d = 0; d < n_distance_x - 2; ++d )
724 distance_x[ d + 1 ] = (-
mp_halfFOV[ 0 ]) + ( index[ 0 ] + idx_orient_trans + ( incr_orient_trans * d ) ) * mp_sizeVox[ 0 ];
728 for( int16_t d = 0; d < n_distance_x - 1; ++d )
729 distance_x[ d ] = ::fabs( distance_x[ d + 1 ] - distance_x[ d ] );
732 int16_t
const n_distance_z = ::abs( index[ 2 ] - index[ 3 ] ) + 2;
734 distance_z[ 0 ] = pos[ 2 ];
735 distance_z[ n_distance_z - 1 ] = pos[ 3 ];
737 if( n_distance_z > 2 )
739 for( int16_t d = 0; d < n_distance_z - 2; ++d )
740 distance_z[ d + 1 ] = (-
mp_halfFOV[ 2 ]) + ( index[ 2 ] + idx_orient_axial + ( incr_orient_axial * d ) ) * mp_sizeVox[ 2 ];
744 for( int16_t d = 0; d < n_distance_z - 1; ++d )
745 distance_z[ d ] = ::fabs( distance_z[ d + 1 ] - distance_z[ d ] );
748 int16_t index_x, index_z;
749 for( int16_t jj = 0; jj < n_distance_z - 1; ++jj )
751 index_z = index[ 2 ] + jj * incr_orient_axial;
752 if( index_z < 0 || index_z >
mp_nbVox[ 2 ] - 1 )
continue;
754 for( int16_t ii = 0; ii < n_distance_x - 1; ++ii )
756 index_x = index[ 0 ] + ii * incr_orient_trans;
757 if( index_x < 0 || index_x >
mp_nbVox[ 0 ] - 1 )
continue;
759 ap_ProjectionLine->
AddVoxel(a_direction, index_x + j *
mp_nbVox[ 0 ] + index_z * m_nbVoxXY, final_weight * distance_z[ jj ] * distance_x[ ii ]);
778 Cerr(
"***** iProjectorDistanceDriven::ProjectTOFListmode() -> Called while not initialized !" << endl);
783 #ifdef CASTOR_VERBOSE 786 string direction =
"";
787 if (a_direction==
FORWARD) direction =
"forward";
788 else direction =
"backward";
789 Cout(
"iProjectorDistanceDriven::Project with TOF measurement -> Project line '" << ap_ProjectionLine <<
"' in " << direction <<
" direction" << endl);
846 &p1_x[1], &p1_y[1], &p1_z[1],
847 &p2_x[1], &p2_y[1], &p2_z[1]
850 Cerr(
"***** iProjectorDistanceDriven::ProjectWithoutTOF() -> A problem occurred while getting the edges' center positions !" << endl);
861 p1_x[ 0 ] = p1[ 0 ]; p1_y[ 0 ] = p1[ 1 ]; p1_z[ 0 ] = p1[ 2 ];
864 p2_x[ 0 ] = p2[ 0 ]; p2_y[ 0 ] = p2[ 1 ]; p2_z[ 0 ] = p2[ 2 ];
873 for(
int p = 0; p < 5; ++p )
875 r[ p ][ 0 ] = p2_x[ p ] - p1_x[ p ];
876 r[ p ][ 1 ] = p2_y[ p ] - p1_y[ p ];
877 r[ p ][ 2 ] = p2_z[ p ] - p1_z[ p ];
882 r[ 0 ][ 0 ] * r[ 0 ][ 0 ],
883 r[ 0 ][ 1 ] * r[ 0 ][ 1 ],
884 r[ 0 ][ 2 ] * r[ 0 ][ 2 ]
889 HPFLTNB alpha_min = 0.0, alpha_max = 1.0;
893 HPFLTNB alpha_x_min[ 4 ], alpha_x_max[ 4 ];
894 HPFLTNB alpha_y_min[ 4 ], alpha_y_max[ 4 ];
895 HPFLTNB alpha_z_min[ 4 ], alpha_z_max[ 4 ];
929 HPFLTNB tof_sigma_sqrt2 = sqrt(2.)*tof_sigma;
937 HPFLTNB lor_tof_center = length_LOR * 0.5 + tof_delta;
940 HPFLTNB tof_edge_low[] = {0,0,0};
942 HPFLTNB tof_edge_high[] = {0,0,0};
943 HPFLTNB tof_center[] = {0,0,0};
947 for (
int ax=0;ax<3;ax++)
950 tof_center[ax] = p1[ax] + lor_tof_center * r[0][ax] / length_LOR;
953 tof_edge_low[ax] = tof_center[ax] - tof_half_span * fabs(r[0][ax]) / length_LOR;
954 tof_index = max( (
INTNB)::floor( (tof_edge_low[ax] - (-
mp_halfFOV[ax])) / mp_sizeVox[ax] ), (
INTNB)0);
956 if (tof_index>
mp_nbVox[ax]-1)
return 0;
960 tof_edge_high[ax] = tof_center[ax] + tof_half_span * fabs(r[0][ax]) / length_LOR;
963 if (tof_index<0)
return 0;
968 float const angle = std::acos( ( r[ 0 ][ 0 ] ) / ( std::sqrt( r2[ 0 ] + r2[ 1 ] ) ) ) * 180.0f / M_PI;
971 if( ( angle >= 0.0 && angle <= 45.0 ) || ( angle >= 135.0 && angle <= 180.0 ) )
976 alpha_x_min[ 0 ] = ( tof_edge_low[ 0 ] - p1_x[ 0 ] ) / r[ 0 ][ 0 ];
977 alpha_x_min[ 1 ] = ( tof_edge_high[ 0 ] - p1_x[ 0 ] ) / r[ 0 ][ 0 ];
978 alpha_x_max[ 0 ] = alpha_x_min[ 0 ];
979 alpha_x_max[ 1 ] = alpha_x_min[ 1 ];
980 alpha_min = std::max( alpha_min, std::min( alpha_x_min[ 0 ], alpha_x_min[ 1 ] ) );
981 alpha_max = std::min( alpha_max, std::max( alpha_x_max[ 0 ], alpha_x_max[ 1 ] ) );
985 if( r[ 1 ][ 1 ] != 0 )
987 alpha_y_min[ 0 ] = ( tof_edge_low[ 1 ] - p1_y[ 1 ] ) / r[ 1 ][ 1 ];
988 alpha_y_min[ 1 ] = ( tof_edge_high[ 1 ] - p1_y[ 1 ] ) / r[ 1 ][ 1 ];
989 alpha_y_max[ 0 ] = alpha_y_min[ 0 ];
990 alpha_y_max[ 1 ] = alpha_y_min[ 1 ];
994 alpha_y_min[ 0 ] = 0.0;
995 alpha_y_min[ 1 ] = 0.0;
996 alpha_y_max[ 0 ] = 1.0;
997 alpha_y_max[ 1 ] = 1.0;
1000 if( r[ 2 ][ 1 ] != 0 )
1002 alpha_y_min[ 2 ] = ( tof_edge_low[ 1 ] - p1_y[ 2 ] ) / r[ 2 ][ 1 ];
1003 alpha_y_min[ 3 ] = ( tof_edge_high[ 1 ] - p1_y[ 2 ] ) / r[ 2 ][ 1 ];
1004 alpha_y_max[ 2 ] = alpha_y_min[ 2 ];
1005 alpha_y_max[ 3 ] = alpha_y_min[ 3 ];
1009 alpha_y_min[ 2 ] = 0.0;
1010 alpha_y_min[ 3 ] = 0.0;
1011 alpha_y_max[ 2 ] = 1.0;
1012 alpha_y_max[ 3 ] = 1.0;
1016 alpha_min = std::max( alpha_min,
1017 alpha_y_min[ std::minmax_element( alpha_y_min, alpha_y_min + 4 ).first - alpha_y_min ] );
1019 alpha_max = std::min( alpha_max,
1020 alpha_y_max[ std::minmax_element( alpha_y_max, alpha_y_max + 4 ).second - alpha_y_max ] );
1023 if( r[ 3 ][ 2 ] != 0 )
1025 alpha_z_min[ 0 ] = ( tof_edge_low[ 2 ] - p1_z[ 3 ] ) / r[ 3 ][ 2 ];
1026 alpha_z_min[ 1 ] = ( tof_edge_high[ 2 ] - p1_z[ 3 ] ) / r[ 3 ][ 2 ];
1027 alpha_z_max[ 0 ] = alpha_z_min[ 0 ];
1028 alpha_z_max[ 1 ] = alpha_z_min[ 1 ];
1032 alpha_z_min[ 0 ] = 0.0;
1033 alpha_z_min[ 1 ] = 0.0;
1034 alpha_z_max[ 0 ] = 1.0;
1035 alpha_z_max[ 1 ] = 1.0;
1038 if( r[ 4 ][ 2 ] != 0 )
1040 alpha_z_min[ 2 ] = ( tof_edge_low[ 2 ] - p1_z[ 4 ] ) / r[ 4 ][ 2 ];
1041 alpha_z_min[ 3 ] = ( tof_edge_high[ 2 ] - p1_z[ 4 ] ) / r[ 4 ][ 2 ];
1042 alpha_z_max[ 2 ] = alpha_z_min[ 2 ];
1043 alpha_z_max[ 3 ] = alpha_z_min[ 3 ];
1047 alpha_z_min[ 2 ] = 0.0;
1048 alpha_z_min[ 3 ] = 0.0;
1049 alpha_z_max[ 2 ] = 1.0;
1050 alpha_z_max[ 3 ] = 1.0;
1054 alpha_min = std::max( alpha_min,
1055 alpha_z_min[ std::minmax_element( alpha_z_min, alpha_z_min + 4 ).first
1058 alpha_max = std::min( alpha_max,
1059 alpha_z_max[ std::minmax_element( alpha_z_max, alpha_z_max + 4 ).second
1062 if( alpha_max <= alpha_min )
return 0;
1065 int16_t i_min = 0, i_max = 0;
1066 if( r[ 0 ][ 0 ] > 0.0 )
1069 i_max = ::floor(
m_toleranceX + ( p1_x[ 0 ] + alpha_max * r[ 0 ][ 0 ] - (-
mp_halfFOV[ 0 ]) ) / mp_sizeVox[ 0 ] );
1071 else if( r[ 0 ][ 0 ] < 0.0 )
1074 i_max = ::floor(
m_toleranceX + ( p1_x[ 0 ] + alpha_min * r[ 0 ][ 0 ] - (-
mp_halfFOV[ 0 ]) ) / mp_sizeVox[ 0 ] );
1079 HPFLTNB const factor( ::fabs( r[ 0 ][ 0 ] ) / ::sqrt( r2[ 0 ] + r2[ 1 ] + r2[ 2 ] ) );
1080 HPFLTNB weight( mp_sizeVox[ 0 ] / factor );
1081 HPFLTNB const factor_for_tof( length_LOR / r[ 0 ][ 0 ] );
1085 for( uint8_t p = 0; p < 4; ++p )
1088 ri[ p ][ 1 ] = r[ p + 1 ][ 1 ] / r[ p + 1 ][ 0 ];
1089 ri[ p ][ 2 ] = r[ p + 1 ][ 2 ] / r[ p + 1 ][ 0 ];
1093 int8_t incr_orient_trans = 0;
1094 int8_t idx_orient_trans = 0;
1097 int8_t
const incr_orient_axial = p2_z[ 3 ] < p2_z[ 4 ] ? 1 : -1;
1101 int8_t
const idx_orient_axial = p2_z[ 3 ] < p2_z[ 4 ] ? 1 : 0;
1104 HPFLTNB const offset = (-
mp_halfFOV[ 0 ]) + ( mp_sizeVox[ 0 ] * 0.5 ) - p1_x[ 0 ];
1107 for( int16_t i = i_min; i < i_max; ++i )
1110 HPFLTNB const step = offset + i * mp_sizeVox[ 0 ];
1112 pos[ 0 ] = p1_y[ 1 ] + step * ri[ 0 ][ 1 ];
1113 pos[ 1 ] = p1_y[ 2 ] + step * ri[ 1 ][ 1 ];
1115 pos[ 2 ] = p1_z[ 3 ] + step * ri[ 2 ][ 2 ];
1116 pos[ 3 ] = p1_z[ 4 ] + step * ri[ 3 ][ 2 ];
1119 w1 = ::fabs( pos[ 0 ] - pos[ 1 ] );
1120 w2 = ::fabs( pos[ 2 ] - pos[ 3 ] );
1122 if( ( w1 * w2 ) != 0 ) final_weight = weight / ( w1 * w2 );
1135 bool test_index = (index[ 0 ] >= 0 && index[ 2 ] >= 0 && index[ 1 ] >= 0 && index[ 3 ] >= 0
1139 if( index[ 0 ] < index[ 1 ] )
1141 incr_orient_trans = 1;
1142 idx_orient_trans = 1;
1144 else if( index[ 0 ] > index[ 1 ] )
1146 incr_orient_trans = -1;
1147 idx_orient_trans = 0;
1151 int16_t
const n_distance_y = ::abs( index[ 0 ] - index[ 1 ] ) + 2;
1153 distance_y[ 0 ] = pos[ 0 ];
1154 distance_y[ n_distance_y - 1 ] = pos[ 1 ];
1156 if( n_distance_y > 2 )
1158 for( int16_t d = 0; d < n_distance_y - 2; ++d )
1159 distance_y[ d + 1 ] = (-
mp_halfFOV[ 1 ]) + ( index[ 0 ] + idx_orient_trans + ( incr_orient_trans * d ) ) * mp_sizeVox[ 1 ];
1163 for( int16_t d = 0; d < n_distance_y - 1; ++d )
1164 distance_y[ d ] = ::fabs( distance_y[ d + 1 ] - distance_y[ d ] );
1167 int16_t
const n_distance_z = ::abs( index[ 2 ] - index[ 3 ] ) + 2;
1169 distance_z[ 0 ] = pos[ 2 ];
1170 distance_z[ n_distance_z - 1 ] = pos[ 3 ];
1172 if( n_distance_z > 2 )
1174 for( int16_t d = 0; d < n_distance_z - 2; ++d )
1175 distance_z[ d + 1 ] = (-
mp_halfFOV[ 2 ]) + ( index[ 2 ] + idx_orient_axial + ( incr_orient_axial * d ) ) * mp_sizeVox[ 2 ];
1179 for( int16_t d = 0; d < n_distance_z - 1; ++d )
1180 distance_z[ d ] = ::fabs( distance_z[ d + 1 ] - distance_z[ d ] );
1197 HPFLTNB temp_erf = std::min(tof_half_span, std::max(-tof_half_span, lor_tof_center -
m_TOFBinSizeInMm/2. - step * factor_for_tof));
1198 HPFLTNB prev_erf = erf(temp_erf/tof_sigma_sqrt2);
1199 temp_erf = std::min(tof_half_span, std::max(-tof_half_span, lor_tof_center +
m_TOFBinSizeInMm/2. - step * factor_for_tof));
1200 HPFLTNB new_erf = erf(temp_erf/tof_sigma_sqrt2);
1207 HPFLTNB temp = (step * factor_for_tof - lor_tof_center) / tof_sigma;
1213 int16_t index_y, index_z;
1214 for( int16_t jj = 0; jj < n_distance_z - 1; ++jj )
1216 index_z = index[ 2 ] + jj * incr_orient_axial;
1217 if( index_z < 0 || index_z >
mp_nbVox[ 2 ] - 1 )
continue;
1219 for( int16_t ii = 0; ii < n_distance_y - 1; ++ii )
1221 index_y = index[ 0 ] + ii * incr_orient_trans;
1222 if( index_y < 0 || index_y >
mp_nbVox[ 1 ] - 1 )
continue;
1224 ap_ProjectionLine->
AddVoxel(a_direction, i + index_y *
mp_nbVox[ 0 ] + index_z * m_nbVoxXY, final_weight * distance_z[ jj ] * distance_y[ ii ] * tof_weight);
1234 if( r[ 1 ][ 0 ] != 0.0 )
1236 alpha_x_min[ 0 ] = ( tof_edge_low[ 0 ] - p1_x[ 1 ] ) / r[ 1 ][ 0 ];
1237 alpha_x_min[ 1 ] = ( tof_edge_high[ 0 ] - p1_x[ 1 ] ) / r[ 1 ][ 0 ];
1238 alpha_x_max[ 0 ] = alpha_x_min[ 0 ];
1239 alpha_x_max[ 1 ] = alpha_x_min[ 1 ];
1243 alpha_x_min[ 0 ] = 0.0;
1244 alpha_x_min[ 1 ] = 0.0;
1245 alpha_x_max[ 0 ] = 1.0;
1246 alpha_x_max[ 1 ] = 1.0;
1249 if( r[ 2 ][ 0 ] != 0 )
1251 alpha_x_min[ 2 ] = ( tof_edge_low[ 0 ] - p1_x[ 2 ] ) / r[ 2 ][ 0 ];
1252 alpha_x_min[ 3 ] = ( tof_edge_high[ 0 ] - p1_x[ 2 ] ) / r[ 2 ][ 0 ];
1253 alpha_x_max[ 2 ] = alpha_x_min[ 2 ];
1254 alpha_x_max[ 3 ] = alpha_x_min[ 3 ];
1258 alpha_x_min[ 2 ] = 0.0;
1259 alpha_x_min[ 3 ] = 0.0;
1260 alpha_x_max[ 2 ] = 1.0;
1261 alpha_x_max[ 3 ] = 1.0;
1265 alpha_min = std::max( alpha_min,
1266 alpha_x_min[ std::minmax_element( alpha_x_min, alpha_x_min + 4 ).first - alpha_x_min ] );
1268 alpha_max = std::min( alpha_max,
1269 alpha_x_max[ std::minmax_element( alpha_x_max, alpha_x_max + 4 ).second - alpha_x_max ] );
1273 alpha_y_min[ 0 ] = ( tof_edge_low[1] - p1_y[ 0 ] ) / r[ 0 ][ 1 ];
1274 alpha_y_min[ 1 ] = ( tof_edge_high[1] - p1_y[ 0 ] ) / r[ 0 ][ 1 ];
1275 alpha_y_max[ 0 ] = alpha_y_min[ 0 ];
1276 alpha_y_max[ 1 ] = alpha_y_min[ 1 ];
1277 alpha_min = std::max( alpha_min,
1278 std::min( alpha_y_min[ 0 ], alpha_y_min[ 1 ] ) );
1279 alpha_max = std::min( alpha_max,
1280 std::max( alpha_y_max[ 0 ], alpha_y_max[ 1 ] ) );
1283 if( r[ 3 ][ 2 ] != 0 )
1285 alpha_z_min[ 0 ] = ( tof_edge_low[ 2 ] - p1_z[ 3 ] ) / r[ 3 ][ 2 ];
1286 alpha_z_min[ 1 ] = ( tof_edge_high[ 2 ]- p1_z[ 3 ] ) / r[ 3 ][ 2 ];
1287 alpha_z_max[ 0 ] = alpha_z_min[ 0 ];
1288 alpha_z_max[ 1 ] = alpha_z_min[ 1 ];
1292 alpha_z_min[ 0 ] = 0.0;
1293 alpha_z_min[ 1 ] = 0.0;
1294 alpha_z_max[ 0 ] = 1.0;
1295 alpha_z_max[ 1 ] = 1.0;
1298 if( r[ 4 ][ 2 ] != 0 )
1300 alpha_z_min[ 2 ] = ( tof_edge_low[ 2 ] - p1_z[ 4 ] ) / r[ 4 ][ 2 ];
1301 alpha_z_min[ 3 ] = ( tof_edge_high[ 2 ] - p1_z[ 4 ] ) / r[ 4 ][ 2 ];
1302 alpha_z_max[ 2 ] = alpha_z_min[ 2 ];
1303 alpha_z_max[ 3 ] = alpha_z_min[ 3 ];
1307 alpha_z_min[ 2 ] = 0.0;
1308 alpha_z_min[ 3 ] = 0.0;
1309 alpha_z_max[ 2 ] = 1.0;
1310 alpha_z_max[ 3 ] = 1.0;
1314 alpha_min = std::max( alpha_min, alpha_z_min[ std::minmax_element( alpha_z_min, alpha_z_min + 4 ).first - alpha_z_min ] );
1316 alpha_max = std::min( alpha_max, alpha_z_max[ std::minmax_element( alpha_z_max, alpha_z_max + 4 ).second - alpha_z_max ] );
1318 if( alpha_max <= alpha_min )
return 0;
1321 int16_t j_min = 0, j_max = 0;
1322 if( r[ 0 ][ 1 ] > 0.0 )
1325 j_max = ::floor(
m_toleranceY + ( p1_y[ 0 ] + alpha_max * r[ 0 ][ 1 ] - (-
mp_halfFOV[ 1 ]) ) / mp_sizeVox[ 1 ] );
1327 else if( r[ 0 ][ 1 ] < 0.0 )
1330 j_max = ::floor(
m_toleranceY + ( p1_y[ 0 ] + alpha_min * r[ 0 ][ 1 ] - (-
mp_halfFOV[ 1 ]) ) / mp_sizeVox[ 1 ] );
1335 HPFLTNB const factor( ::fabs( r[ 0 ][ 1 ] ) / ::sqrt( r2[ 0 ] + r2[ 1 ] + r2[ 2 ] ) );
1336 HPFLTNB weight( mp_sizeVox[ 1 ] / factor );
1337 HPFLTNB const factor_for_tof( length_LOR / r[ 0 ][ 1 ] );
1341 for( uint8_t p = 0; p < 4; ++p )
1343 ri[ p ][ 0 ] = r[ p + 1 ][ 0 ] / r[ p + 1 ][ 1 ];
1345 ri[ p ][ 2 ] = r[ p + 1 ][ 2 ] / r[ p + 1 ][ 1 ];
1349 int8_t incr_orient_trans = 0;
1350 int8_t idx_orient_trans = 0;
1353 int8_t
const incr_orient_axial = p2_z[ 3 ] < p2_z[ 4 ] ? 1 : -1;
1355 int8_t
const idx_orient_axial = p2_z[ 3 ] < p2_z[ 4 ] ? 1 : 0;
1358 HPFLTNB const offset = (-
mp_halfFOV[ 1 ]) + ( mp_sizeVox[ 1 ] * 0.5 ) - p1_y[ 0 ];
1361 for( int16_t j = j_min; j < j_max; ++j )
1364 HPFLTNB const step = offset + j * mp_sizeVox[ 1 ];
1366 pos[ 0 ] = p1_x[ 1 ] + step * ri[ 0 ][ 0 ];
1367 pos[ 1 ] = p1_x[ 2 ] + step * ri[ 1 ][ 0 ];
1369 pos[ 2 ] = p1_z[ 3 ] + step * ri[ 2 ][ 2 ];
1370 pos[ 3 ] = p1_z[ 4 ] + step * ri[ 3 ][ 2 ];
1373 w1 = ::fabs( pos[ 0 ] - pos[ 1 ] );
1374 w2 = ::fabs( pos[ 2 ] - pos[ 3 ] );
1376 if( ( w1 * w2 ) != 0 ) final_weight = weight / ( w1 * w2 );
1389 bool test_index = (index[ 0 ] >= 0 && index[ 2 ] >= 0 && index[ 1 ] >= 0 && index[ 3 ] >= 0
1393 if( index[ 0 ] < index[ 1 ] )
1395 incr_orient_trans = 1;
1396 idx_orient_trans = 1;
1398 else if( index[ 0 ] > index[ 1 ] )
1400 incr_orient_trans = -1;
1401 idx_orient_trans = 0;
1405 int16_t
const n_distance_x = ::abs( index[ 0 ] - index[ 1 ] ) + 2;
1407 distance_x[ 0 ] = pos[ 0 ];
1408 distance_x[ n_distance_x - 1 ] = pos[ 1 ];
1410 if( n_distance_x > 2 )
1412 for( int16_t d = 0; d < n_distance_x - 2; ++d )
1413 distance_x[ d + 1 ] = (-
mp_halfFOV[ 0 ]) + ( index[ 0 ] + idx_orient_trans + ( incr_orient_trans * d ) ) * mp_sizeVox[ 0 ];
1417 for( int16_t d = 0; d < n_distance_x - 1; ++d )
1418 distance_x[ d ] = ::fabs( distance_x[ d + 1 ] - distance_x[ d ] );
1421 int16_t
const n_distance_z = ::abs( index[ 2 ] - index[ 3 ] ) + 2;
1423 distance_z[ 0 ] = pos[ 2 ];
1424 distance_z[ n_distance_z - 1 ] = pos[ 3 ];
1426 if( n_distance_z > 2 )
1428 for( int16_t d = 0; d < n_distance_z - 2; ++d )
1429 distance_z[ d + 1 ] = (-
mp_halfFOV[ 2 ]) + ( index[ 2 ] + idx_orient_axial + ( incr_orient_axial * d ) ) * mp_sizeVox[ 2 ];
1433 for( int16_t d = 0; d < n_distance_z - 1; ++d )
1434 distance_z[ d ] = ::fabs( distance_z[ d + 1 ] - distance_z[ d ] );
1451 HPFLTNB temp_erf = std::min(tof_half_span, std::max(-tof_half_span, lor_tof_center -
m_TOFBinSizeInMm/2. - step * factor_for_tof));
1452 HPFLTNB prev_erf = erf(temp_erf/tof_sigma_sqrt2);
1453 temp_erf = std::min(tof_half_span, std::max(-tof_half_span, lor_tof_center +
m_TOFBinSizeInMm/2. - step * factor_for_tof));
1454 HPFLTNB new_erf = erf(temp_erf/tof_sigma_sqrt2);
1461 HPFLTNB temp = (step * factor_for_tof - lor_tof_center) / tof_sigma;
1467 int16_t index_x, index_z;
1468 for( int16_t jj = 0; jj < n_distance_z - 1; ++jj )
1470 index_z = index[ 2 ] + jj * incr_orient_axial;
1471 if( index_z < 0 || index_z >
mp_nbVox[ 2 ] - 1 )
continue;
1473 for( int16_t ii = 0; ii < n_distance_x - 1; ++ii )
1475 index_x = index[ 0 ] + ii * incr_orient_trans;
1476 if( index_x < 0 || index_x >
mp_nbVox[ 0 ] - 1 )
continue;
1478 ap_ProjectionLine->
AddVoxel(a_direction, index_x + j *
mp_nbVox[ 0 ] + index_z * m_nbVoxXY, final_weight * distance_z[ jj ] * distance_x[ ii ] * tof_weight);
1497 Cerr(
"***** iProjectorDistanceDriven::ProjectTOFHistogram() -> Called while not initialized !" << endl);
1502 #ifdef CASTOR_VERBOSE 1505 string direction =
"";
1506 if (a_direction==
FORWARD) direction =
"forward";
1507 else direction =
"backward";
1508 Cout(
"iProjectorDistanceDriven::Project with TOF bins -> Project line '" << ap_ProjectionLine <<
"' in " << direction <<
" direction" << endl);
1554 HPFLTNB length_LOR_half = length_LOR * 0.5;
1558 INTNB tof_half_nb_bins = tof_nb_bins/2;
1562 HPFLTNB tof_sigma_sqrt2 = sqrt(2.)*tof_sigma;
1568 HPFLTNB prev_erf = 0., new_erf = 0.;
1571 INTNB tof_bin_last = tof_half_nb_bins;
1572 INTNB tof_bin_first = -tof_half_nb_bins;
1580 INTNB tof_bin_first_for_voxel = 0, tof_bin_last_for_voxel = 0;
1596 &p1_x[1], &p1_y[1], &p1_z[1],
1597 &p2_x[1], &p2_y[1], &p2_z[1]
1600 Cerr(
"***** iProjectorDistanceDriven::ProjectWithoutTOF() -> A problem occurred while getting the edges' center positions !" << endl);
1611 p1_x[ 0 ] = p1[ 0 ]; p1_y[ 0 ] = p1[ 1 ]; p1_z[ 0 ] = p1[ 2 ];
1614 p2_x[ 0 ] = p2[ 0 ]; p2_y[ 0 ] = p2[ 1 ]; p2_z[ 0 ] = p2[ 2 ];
1623 for(
int p = 0; p < 5; ++p )
1625 r[ p ][ 0 ] = p2_x[ p ] - p1_x[ p ];
1626 r[ p ][ 1 ] = p2_y[ p ] - p1_y[ p ];
1627 r[ p ][ 2 ] = p2_z[ p ] - p1_z[ p ];
1632 r[ 0 ][ 0 ] * r[ 0 ][ 0 ],
1633 r[ 0 ][ 1 ] * r[ 0 ][ 1 ],
1634 r[ 0 ][ 2 ] * r[ 0 ][ 2 ]
1639 HPFLTNB alpha_min = 0.0, alpha_max = 1.0;
1643 HPFLTNB alpha_x_min[ 4 ], alpha_x_max[ 4 ];
1644 HPFLTNB alpha_y_min[ 4 ], alpha_y_max[ 4 ];
1645 HPFLTNB alpha_z_min[ 4 ], alpha_z_max[ 4 ];
1670 float const angle = std::acos( ( r[ 0 ][ 0 ] ) / ( std::sqrt( r2[ 0 ] + r2[ 1 ] ) ) ) * 180.0f / M_PI;
1673 if( ( angle >= 0.0 && angle <= 45.0 ) || ( angle >= 135.0 && angle <= 180.0 ) )
1677 alpha_x_min[ 0 ] = ( (-
mp_halfFOV[ 0 ]) - p1_x[ 0 ] ) / r[ 0 ][ 0 ];
1678 alpha_x_min[ 1 ] = (
mp_halfFOV[ 0 ] - p1_x[ 0 ] ) / r[ 0 ][ 0 ];
1679 alpha_x_max[ 0 ] = alpha_x_min[ 0 ];
1680 alpha_x_max[ 1 ] = alpha_x_min[ 1 ];
1681 alpha_min = std::max( alpha_min, std::min( alpha_x_min[ 0 ], alpha_x_min[ 1 ] ) );
1682 alpha_max = std::min( alpha_max, std::max( alpha_x_max[ 0 ], alpha_x_max[ 1 ] ) );
1686 if( r[ 1 ][ 1 ] != 0.0 )
1688 alpha_y_min[ 0 ] = ( (-
mp_halfFOV[ 1 ]) - p1_y[ 1 ] ) / r[ 1 ][ 1 ];
1689 alpha_y_min[ 1 ] = (
mp_halfFOV[ 1 ] - p1_y[ 1 ] ) / r[ 1 ][ 1 ];
1690 alpha_y_max[ 0 ] = alpha_y_min[ 0 ];
1691 alpha_y_max[ 1 ] = alpha_y_min[ 1 ];
1695 alpha_y_min[ 0 ] = 0.0;
1696 alpha_y_min[ 1 ] = 0.0;
1697 alpha_y_max[ 0 ] = 1.0;
1698 alpha_y_max[ 1 ] = 1.0;
1701 if( r[ 2 ][ 1 ] != 0.0 )
1703 alpha_y_min[ 2 ] = ( (-
mp_halfFOV[ 1 ]) - p1_y[ 2 ] ) / r[ 2 ][ 1 ];
1704 alpha_y_min[ 3 ] = (
mp_halfFOV[ 1 ] - p1_y[ 2 ] ) / r[ 2 ][ 1 ];
1705 alpha_y_max[ 2 ] = alpha_y_min[ 2 ];
1706 alpha_y_max[ 3 ] = alpha_y_min[ 3 ];
1710 alpha_y_min[ 2 ] = 0.0;
1711 alpha_y_min[ 3 ] = 0.0;
1712 alpha_y_max[ 2 ] = 1.0;
1713 alpha_y_max[ 3 ] = 1.0;
1717 alpha_min = std::max( alpha_min,
1718 alpha_y_min[ std::minmax_element( alpha_y_min, alpha_y_min + 4 ).first - alpha_y_min ] );
1720 alpha_max = std::min( alpha_max,
1721 alpha_y_max[ std::minmax_element( alpha_y_max, alpha_y_max + 4 ).second - alpha_y_max ] );
1724 if( r[ 3 ][ 2 ] != 0.0 )
1726 alpha_z_min[ 0 ] = ( (-
mp_halfFOV[ 2 ]) - p1_z[ 3 ] ) / r[ 3 ][ 2 ];
1727 alpha_z_min[ 1 ] = (
mp_halfFOV[ 2 ] - p1_z[ 3 ] ) / r[ 3 ][ 2 ];
1728 alpha_z_max[ 0 ] = alpha_z_min[ 0 ];
1729 alpha_z_max[ 1 ] = alpha_z_min[ 1 ];
1733 alpha_z_min[ 0 ] = 0.0;
1734 alpha_z_min[ 1 ] = 0.0;
1735 alpha_z_max[ 0 ] = 1.0;
1736 alpha_z_max[ 1 ] = 1.0;
1739 if( r[ 4 ][ 2 ] != 0.0 )
1741 alpha_z_min[ 2 ] = ( (-
mp_halfFOV[ 2 ]) - p1_z[ 4 ] ) / r[ 4 ][ 2 ];
1742 alpha_z_min[ 3 ] = (
mp_halfFOV[ 2 ] - p1_z[ 4 ] ) / r[ 4 ][ 2 ];
1743 alpha_z_max[ 2 ] = alpha_z_min[ 2 ];
1744 alpha_z_max[ 3 ] = alpha_z_min[ 3 ];
1748 alpha_z_min[ 2 ] = 0.0;
1749 alpha_z_min[ 3 ] = 0.0;
1750 alpha_z_max[ 2 ] = 1.0;
1751 alpha_z_max[ 3 ] = 1.0;
1755 alpha_min = std::max( alpha_min,
1756 alpha_z_min[ std::minmax_element( alpha_z_min, alpha_z_min + 4 ).first
1759 alpha_max = std::min( alpha_max,
1760 alpha_z_max[ std::minmax_element( alpha_z_max, alpha_z_max + 4 ).second
1763 if( alpha_max <= alpha_min )
return 0;
1768 for (
INTNB tof_bin=0; tof_bin<tof_nb_bins; tof_bin++) tof_weights_temp[tof_bin] = 0.;
1771 int16_t i_min = 0, i_max = 0;
1772 if( r[ 0 ][ 0 ] > 0.0 )
1775 i_max = ::floor(
m_toleranceX + ( p1_x[ 0 ] + alpha_max * r[ 0 ][ 0 ] - (-
mp_halfFOV[ 0 ]) ) / mp_sizeVox[ 0 ] );
1777 else if( r[ 0 ][ 0 ] < 0.0 )
1780 i_max = ::floor(
m_toleranceX + ( p1_x[ 0 ] + alpha_min * r[ 0 ][ 0 ] - (-
mp_halfFOV[ 0 ]) ) / mp_sizeVox[ 0 ] );
1785 HPFLTNB const factor( ::fabs( r[ 0 ][ 0 ] ) / ::sqrt( r2[ 0 ] + r2[ 1 ] + r2[ 2 ] ) );
1786 HPFLTNB const factor_for_tof( length_LOR / r[ 0 ][ 0 ] );
1787 HPFLTNB weight( mp_sizeVox[ 0 ] / factor );
1791 for( uint8_t p = 0; p < 4; ++p )
1794 ri[ p ][ 1 ] = r[ p + 1 ][ 1 ] / r[ p + 1 ][ 0 ];
1795 ri[ p ][ 2 ] = r[ p + 1 ][ 2 ] / r[ p + 1 ][ 0 ];
1799 int8_t incr_orient_trans = 0;
1800 int8_t idx_orient_trans = 0;
1803 int8_t
const incr_orient_axial = p2_z[ 3 ] < p2_z[ 4 ] ? 1 : -1;
1807 int8_t
const idx_orient_axial = p2_z[ 3 ] < p2_z[ 4 ] ? 1 : 0;
1810 HPFLTNB const offset = (-
mp_halfFOV[ 0 ]) + ( mp_sizeVox[ 0 ] * 0.5 ) - p1_x[ 0 ];
1813 for( int16_t i = i_min; i < i_max; ++i )
1816 HPFLTNB const step = offset + i * mp_sizeVox[ 0 ];
1818 pos[ 0 ] = p1_y[ 1 ] + step * ri[ 0 ][ 1 ];
1819 pos[ 1 ] = p1_y[ 2 ] + step * ri[ 1 ][ 1 ];
1821 pos[ 2 ] = p1_z[ 3 ] + step * ri[ 2 ][ 2 ];
1822 pos[ 3 ] = p1_z[ 4 ] + step * ri[ 3 ][ 2 ];
1825 w1 = ::fabs( pos[ 0 ] - pos[ 1 ] );
1826 w2 = ::fabs( pos[ 2 ] - pos[ 3 ] );
1828 if( ( w1 * w2 ) != 0 ) final_weight = weight / ( w1 * w2 );
1841 bool test_index = (index[ 0 ] >= 0 && index[ 2 ] >= 0 && index[ 1 ] >= 0 && index[ 3 ] >= 0
1845 if( index[ 0 ] < index[ 1 ] )
1847 incr_orient_trans = 1;
1848 idx_orient_trans = 1;
1850 else if( index[ 0 ] > index[ 1 ] )
1852 incr_orient_trans = -1;
1853 idx_orient_trans = 0;
1857 int16_t
const n_distance_y = ::abs( index[ 0 ] - index[ 1 ] ) + 2;
1859 distance_y[ 0 ] = pos[ 0 ];
1860 distance_y[ n_distance_y - 1 ] = pos[ 1 ];
1862 if( n_distance_y > 2 )
1864 for( int16_t d = 0; d < n_distance_y - 2; ++d )
1865 distance_y[ d + 1 ] = (-
mp_halfFOV[ 1 ]) + ( index[ 0 ] + idx_orient_trans + ( incr_orient_trans * d ) ) * mp_sizeVox[ 1 ];
1869 for( int16_t d = 0; d < n_distance_y - 1; ++d )
1870 distance_y[ d ] = ::fabs( distance_y[ d + 1 ] - distance_y[ d ] );
1873 int16_t
const n_distance_z = ::abs( index[ 2 ] - index[ 3 ] ) + 2;
1875 distance_z[ 0 ] = pos[ 2 ];
1876 distance_z[ n_distance_z - 1 ] = pos[ 3 ];
1878 if( n_distance_z > 2 )
1880 for( int16_t d = 0; d < n_distance_z - 2; ++d )
1881 distance_z[ d + 1 ] = (-
mp_halfFOV[ 2 ]) + ( index[ 2 ] + idx_orient_axial + ( incr_orient_axial * d ) ) * mp_sizeVox[ 2 ];
1885 for( int16_t d = 0; d < n_distance_z - 1; ++d )
1886 distance_z[ d ] = ::fabs( distance_z[ d + 1 ] - distance_z[ d ] );
1898 tof_bin_first_for_voxel = max(tof_bin_first , (
INTNB)(ceil( (step * factor_for_tof - tof_half_span - length_LOR_half ) /
m_TOFBinSizeInMm )));
1899 tof_bin_last_for_voxel = min(tof_bin_last , (
INTNB)(floor( (step * factor_for_tof + tof_half_span - length_LOR_half) /
m_TOFBinSizeInMm )));
1902 lor_tof_center = length_LOR_half + tof_bin_first_for_voxel *
m_TOFBinSizeInMm;
1905 tof_bin_first_for_voxel += tof_half_nb_bins;
1906 tof_bin_last_for_voxel += tof_half_nb_bins;
1912 HPFLTNB temp = std::min(tof_half_span,std::max(-tof_half_span, lor_tof_center - m_TOFBinSizeInMm/2. - step * factor_for_tof));
1913 prev_erf = erf(temp/tof_sigma_sqrt2);
1918 for (
INTNB tof_bin=tof_bin_first_for_voxel; tof_bin<=tof_bin_last_for_voxel; tof_bin++)
1938 HPFLTNB temp = std::min(tof_half_span,std::max(-tof_half_span, lor_tof_center + m_TOFBinSizeInMm/2. - step * factor_for_tof));
1939 new_erf = erf(temp/tof_sigma_sqrt2);
1940 tof_weights_temp[tof_bin] = 0.5 * fabs(new_erf - prev_erf);
1950 HPFLTNB temp = (step * factor_for_tof - lor_tof_center) / tof_sigma;
1969 int16_t index_y, index_z;
1970 for( int16_t jj = 0; jj < n_distance_z - 1; ++jj )
1972 index_z = index[ 2 ] + jj * incr_orient_axial;
1973 if( index_z < 0 || index_z >
mp_nbVox[ 2 ] - 1 )
continue;
1975 for( int16_t ii = 0; ii < n_distance_y - 1; ++ii )
1977 index_y = index[ 0 ] + ii * incr_orient_trans;
1978 if( index_y < 0 || index_y >
mp_nbVox[ 1 ] - 1 )
continue;
1980 ap_ProjectionLine->
AddVoxelAllTOFBins(a_direction, i + index_y *
mp_nbVox[ 0 ] + index_z * m_nbVoxXY, final_weight * distance_z[ jj ] * distance_y[ ii ], tof_weights_temp, tof_bin_first_for_voxel, tof_bin_last_for_voxel);
1984 delete[] tof_weights_temp;
1990 if( r[ 1 ][ 0 ] != 0.0 )
1992 alpha_x_min[ 0 ] = ( (-
mp_halfFOV[ 0 ]) - p1_x[ 1 ] ) / r[ 1 ][ 0 ];
1993 alpha_x_min[ 1 ] = (
mp_halfFOV[ 0 ] - p1_x[ 1 ] ) / r[ 1 ][ 0 ];
1994 alpha_x_max[ 0 ] = alpha_x_min[ 0 ];
1995 alpha_x_max[ 1 ] = alpha_x_min[ 1 ];
1999 alpha_x_min[ 0 ] = 0.0;
2000 alpha_x_min[ 1 ] = 0.0;
2001 alpha_x_max[ 0 ] = 1.0;
2002 alpha_x_max[ 1 ] = 1.0;
2005 if( r[ 2 ][ 0 ] != 0.0 )
2007 alpha_x_min[ 2 ] = ( (-
mp_halfFOV[ 0 ]) - p1_x[ 2 ] ) / r[ 2 ][ 0 ];
2008 alpha_x_min[ 3 ] = (
mp_halfFOV[ 0 ] - p1_x[ 2 ] ) / r[ 2 ][ 0 ];
2009 alpha_x_max[ 2 ] = alpha_x_min[ 2 ];
2010 alpha_x_max[ 3 ] = alpha_x_min[ 3 ];
2014 alpha_x_min[ 2 ] = 0.0;
2015 alpha_x_min[ 3 ] = 0.0;
2016 alpha_x_max[ 2 ] = 1.0;
2017 alpha_x_max[ 3 ] = 1.0;
2021 alpha_min = std::max( alpha_min,
2022 alpha_x_min[ std::minmax_element( alpha_x_min, alpha_x_min + 4 ).first - alpha_x_min ] );
2024 alpha_max = std::min( alpha_max,
2025 alpha_x_max[ std::minmax_element( alpha_x_max, alpha_x_max + 4 ).second - alpha_x_max ] );
2029 alpha_y_min[ 0 ] = ( (-
mp_halfFOV[ 1 ]) - p1_y[ 0 ] ) / r[ 0 ][ 1 ];
2030 alpha_y_min[ 1 ] = (
mp_halfFOV[ 1 ] - p1_y[ 0 ] ) / r[ 0 ][ 1 ];
2031 alpha_y_max[ 0 ] = alpha_y_min[ 0 ];
2032 alpha_y_max[ 1 ] = alpha_y_min[ 1 ];
2033 alpha_min = std::max( alpha_min,
2034 std::min( alpha_y_min[ 0 ], alpha_y_min[ 1 ] ) );
2035 alpha_max = std::min( alpha_max,
2036 std::max( alpha_y_max[ 0 ], alpha_y_max[ 1 ] ) );
2039 if( r[ 3 ][ 2 ] != 0.0 )
2041 alpha_z_min[ 0 ] = ( (-
mp_halfFOV[ 2 ]) - p1_z[ 3 ] ) / r[ 3 ][ 2 ];
2042 alpha_z_min[ 1 ] = (
mp_halfFOV[ 2 ] - p1_z[ 3 ] ) / r[ 3 ][ 2 ];
2043 alpha_z_max[ 0 ] = alpha_z_min[ 0 ];
2044 alpha_z_max[ 1 ] = alpha_z_min[ 1 ];
2048 alpha_z_min[ 0 ] = 0.0;
2049 alpha_z_min[ 1 ] = 0.0;
2050 alpha_z_max[ 0 ] = 1.0;
2051 alpha_z_max[ 1 ] = 1.0;
2054 if( r[ 4 ][ 2 ] != 0.0 )
2056 alpha_z_min[ 2 ] = ( (-
mp_halfFOV[ 2 ]) - p1_z[ 4 ] ) / r[ 4 ][ 2 ];
2057 alpha_z_min[ 3 ] = (
mp_halfFOV[ 2 ] - p1_z[ 4 ] ) / r[ 4 ][ 2 ];
2058 alpha_z_max[ 2 ] = alpha_z_min[ 2 ];
2059 alpha_z_max[ 3 ] = alpha_z_min[ 3 ];
2063 alpha_z_min[ 2 ] = 0.0;
2064 alpha_z_min[ 3 ] = 0.0;
2065 alpha_z_max[ 2 ] = 1.0;
2066 alpha_z_max[ 3 ] = 1.0;
2070 alpha_min = std::max( alpha_min, alpha_z_min[ std::minmax_element( alpha_z_min, alpha_z_min + 4 ).first - alpha_z_min ] );
2072 alpha_max = std::min( alpha_max, alpha_z_max[ std::minmax_element( alpha_z_max, alpha_z_max + 4 ).second - alpha_z_max ] );
2074 if( alpha_max <= alpha_min )
return 0;
2079 for (
INTNB tof_bin=0; tof_bin<tof_nb_bins; tof_bin++) tof_weights_temp[tof_bin] = 0.;
2082 int16_t j_min = 0, j_max = 0;
2083 if( r[ 0 ][ 1 ] > 0.0 )
2086 j_max = ::floor(
m_toleranceY + ( p1_y[ 0 ] + alpha_max * r[ 0 ][ 1 ] - (-
mp_halfFOV[ 1 ]) ) / mp_sizeVox[ 1 ] );
2088 else if( r[ 0 ][ 1 ] < 0.0 )
2091 j_max = ::floor(
m_toleranceY + ( p1_y[ 0 ] + alpha_min * r[ 0 ][ 1 ] - (-
mp_halfFOV[ 1 ]) ) / mp_sizeVox[ 1 ] );
2096 HPFLTNB const factor( ::fabs( r[ 0 ][ 1 ] ) / ::sqrt( r2[ 0 ] + r2[ 1 ] + r2[ 2 ] ) );
2097 HPFLTNB const factor_for_tof( length_LOR / r[ 0 ][ 1 ] );
2098 HPFLTNB weight( mp_sizeVox[ 1 ] / factor );
2102 for( uint8_t p = 0; p < 4; ++p )
2104 ri[ p ][ 0 ] = r[ p + 1 ][ 0 ] / r[ p + 1 ][ 1 ];
2106 ri[ p ][ 2 ] = r[ p + 1 ][ 2 ] / r[ p + 1 ][ 1 ];
2110 int8_t incr_orient_trans = 0;
2111 int8_t idx_orient_trans = 0;
2114 int8_t
const incr_orient_axial = p2_z[ 3 ] < p2_z[ 4 ] ? 1 : -1;
2116 int8_t
const idx_orient_axial = p2_z[ 3 ] < p2_z[ 4 ] ? 1 : 0;
2119 HPFLTNB const offset = (-
mp_halfFOV[ 1 ]) + ( mp_sizeVox[ 1 ] * 0.5 ) - p1_y[ 0 ];
2122 for( int16_t j = j_min; j < j_max; ++j )
2125 HPFLTNB const step = offset + j * mp_sizeVox[ 1 ];
2127 pos[ 0 ] = p1_x[ 1 ] + step * ri[ 0 ][ 0 ];
2128 pos[ 1 ] = p1_x[ 2 ] + step * ri[ 1 ][ 0 ];
2130 pos[ 2 ] = p1_z[ 3 ] + step * ri[ 2 ][ 2 ];
2131 pos[ 3 ] = p1_z[ 4 ] + step * ri[ 3 ][ 2 ];
2134 w1 = ::fabs( pos[ 0 ] - pos[ 1 ] );
2135 w2 = ::fabs( pos[ 2 ] - pos[ 3 ] );
2137 if( ( w1 * w2 ) != 0 ) final_weight = weight / ( w1 * w2 );
2149 bool test_index = (index[ 0 ] >= 0 && index[ 2 ] >= 0 && index[ 1 ] >= 0 && index[ 3 ] >= 0
2153 if( index[ 0 ] < index[ 1 ] )
2155 incr_orient_trans = 1;
2156 idx_orient_trans = 1;
2158 else if( index[ 0 ] > index[ 1 ] )
2160 incr_orient_trans = -1;
2161 idx_orient_trans = 0;
2165 int16_t
const n_distance_x = ::abs( index[ 0 ] - index[ 1 ] ) + 2;
2167 distance_x[ 0 ] = pos[ 0 ];
2168 distance_x[ n_distance_x - 1 ] = pos[ 1 ];
2170 if( n_distance_x > 2 )
2172 for( int16_t d = 0; d < n_distance_x - 2; ++d )
2173 distance_x[ d + 1 ] = (-
mp_halfFOV[ 0 ]) + ( index[ 0 ] + idx_orient_trans + ( incr_orient_trans * d ) ) * mp_sizeVox[ 0 ];
2177 for( int16_t d = 0; d < n_distance_x - 1; ++d )
2178 distance_x[ d ] = ::fabs( distance_x[ d + 1 ] - distance_x[ d ] );
2181 int16_t
const n_distance_z = ::abs( index[ 2 ] - index[ 3 ] ) + 2;
2183 distance_z[ 0 ] = pos[ 2 ];
2184 distance_z[ n_distance_z - 1 ] = pos[ 3 ];
2186 if( n_distance_z > 2 )
2188 for( int16_t d = 0; d < n_distance_z - 2; ++d )
2189 distance_z[ d + 1 ] = (-
mp_halfFOV[ 2 ]) + ( index[ 2 ] + idx_orient_axial + ( incr_orient_axial * d ) ) * mp_sizeVox[ 2 ];
2193 for( int16_t d = 0; d < n_distance_z - 1; ++d )
2194 distance_z[ d ] = ::fabs( distance_z[ d + 1 ] - distance_z[ d ] );
2200 tof_bin_first_for_voxel = max(tof_bin_first , (
INTNB)(floor( (step * factor_for_tof - tof_half_span - length_LOR_half - m_TOFBinSizeInMm/2.) / m_TOFBinSizeInMm )));
2201 tof_bin_last_for_voxel = min(tof_bin_last , (
INTNB)(ceil( (step * factor_for_tof + tof_half_span - length_LOR_half + m_TOFBinSizeInMm/2.) / m_TOFBinSizeInMm )));
2206 tof_bin_first_for_voxel = max(tof_bin_first , (
INTNB)(ceil( (step * factor_for_tof - tof_half_span - length_LOR_half ) / m_TOFBinSizeInMm )));
2207 tof_bin_last_for_voxel = min(tof_bin_last , (
INTNB)(floor( (step * factor_for_tof + tof_half_span - length_LOR_half) / m_TOFBinSizeInMm )));
2210 lor_tof_center = length_LOR_half + tof_bin_first_for_voxel *
m_TOFBinSizeInMm;
2213 tof_bin_first_for_voxel += tof_half_nb_bins;
2214 tof_bin_last_for_voxel += tof_half_nb_bins;
2220 HPFLTNB temp = std::min(tof_half_span,std::max(-tof_half_span, lor_tof_center - m_TOFBinSizeInMm/2. - step * factor_for_tof));
2221 prev_erf = erf(temp/tof_sigma_sqrt2);
2226 for (
INTNB tof_bin=tof_bin_first_for_voxel; tof_bin<=tof_bin_last_for_voxel; tof_bin++)
2246 HPFLTNB temp = std::min(tof_half_span,std::max(-tof_half_span, lor_tof_center + m_TOFBinSizeInMm/2. - step * factor_for_tof));
2247 new_erf = erf(temp/tof_sigma_sqrt2);
2248 tof_weights_temp[tof_bin] = 0.5 * fabs(new_erf - prev_erf);
2258 HPFLTNB temp = (step * factor_for_tof - lor_tof_center) / tof_sigma;
2277 int16_t index_x, index_z;
2278 for( int16_t jj = 0; jj < n_distance_z - 1; ++jj )
2280 index_z = index[ 2 ] + jj * incr_orient_axial;
2281 if( index_z < 0 || index_z >
mp_nbVox[ 2 ] - 1 )
continue;
2283 for( int16_t ii = 0; ii < n_distance_x - 1; ++ii )
2285 index_x = index[ 0 ] + ii * incr_orient_trans;
2286 if( index_x < 0 || index_x >
mp_nbVox[ 0 ] - 1 )
continue;
2288 ap_ProjectionLine->
AddVoxelAllTOFBins(a_direction, index_x + j *
mp_nbVox[ 0 ] + index_z * m_nbVoxXY, final_weight * distance_z[ jj ] * distance_x[ ii ], tof_weights_temp, tof_bin_first_for_voxel, tof_bin_last_for_voxel);
2293 delete[] tof_weights_temp;
virtual int GetEdgesCenterPositions(int a_index1, int a_index2, FLTNB ap_pos_line_point1[3], FLTNB ap_pos_line_point2[3], FLTNB ap_pos_point1_x[4], FLTNB ap_pos_point1_y[4], FLTNB ap_pos_point1_z[4], FLTNB ap_pos_point2_x[4], FLTNB ap_pos_point2_y[4], FLTNB ap_pos_point2_z[4])=0
bool m_compatibleWithSPECTAttenuationCorrection
int ReadStringOption(const string &a_input, T *ap_return, int a_nbElts, const string &sep, const string &a_option)
Parse the 'a_input' string corresponding to the 'a_option' into 'a_nbElts' elements, using the 'sep' separator. The results are returned in the templated 'ap_return' dynamic templated array. Call "ConvertFromString()" to perform the correct conversion depending on the type of the data to convert.
FLTNB m_TOFGaussianNormCoef
iProjectorDistanceDriven()
The constructor of iProjectorDistanceDriven.
void AddVoxelAllTOFBins(int a_direction, INTNB a_voxelIndex, FLTNB a_voxelWeight, HPFLTNB *a_tofWeights, INTNB a_tofBinFirst, INTNB a_tofBinLast)
INTNB EstimateMaxNumberOfVoxelsPerLine()
This function is used to compute and provide an estimate of the maximum number of voxels that could c...
FLTNB GetTOFMeasurementInPs()
This function is used to get the TOF measurement in ps.
This class is designed to generically described any on-the-fly projector.
#define SPEED_OF_LIGHT_IN_MM_PER_PS
int ReadOptionsList(const string &a_optionsList)
int ProjectWithoutTOF(int a_direction, oProjectionLine *ap_ProjectionLine)
bool m_TOFWeightingFcnPrecomputedFlag
bool m_TOFBinProperProcessingFlag
HPFLTNB * mp_TOFWeightingFcn
oImageDimensionsAndQuantification * mp_ImageDimensionsAndQuantification
FLTNB GetLength()
This function is used to get the length of the line.
int CheckSpecificParameters()
A private function used to check the parameters settings specific to the child projector.
int GetIndex2()
This function is used to get the index associated to point 2.
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)
~iProjectorDistanceDriven()
The destructor of iProjectorDistanceDriven.
int ReadConfigurationFile(const string &a_configurationFile)
FLTNB m_TOFResolutionInMm
int InitializeSpecific()
This function is used to initialize specific stuff to the child projector.
INTNB GetNbVoxXY()
Get the number of voxels in a slice.
This class is designed to manage and store system matrix elements associated to a vEvent...
FLTNB m_TOFPrecomputedSamplingFactor
int ProjectTOFHistogram(int a_direction, oProjectionLine *ap_ProjectionLine)
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).
bool m_compatibleWithCompression
int GetIndex1()
This function is used to get the index associated to point 1.
#define TWO_SQRT_TWO_LN_2
bool IsVoxelMasked(INTNB a_voxIndex)
int ProjectTOFListmode(int a_direction, oProjectionLine *ap_ProjectionLine)
void ShowHelpSpecific()
A function used to show help about the child projector.
INTNB m_TOFWeightingFcnNbSamples