@@ -869,8 +869,8 @@ std::shared_ptr<const DetectorPeakResponse> get_fwhm_coefficients( const RelActC
869
869
paramaters[i] = berstein_coeffs[i];
870
870
871
871
// Set energy range
872
- paramaters[berstein_coeffs.size() ] = lowest_energy;
873
- paramaters[berstein_coeffs.size() + 1] = highest_energy;
872
+ paramaters[num_params - 2 ] = lowest_energy;
873
+ paramaters[num_params - 1] = highest_energy;
874
874
875
875
return input_drf;
876
876
}
@@ -980,13 +980,14 @@ std::shared_ptr<const DetectorPeakResponse> get_fwhm_coefficients( const RelActC
980
980
const std::vector<double> berstein_coeffs = BersteinPolynomial::power_series_to_bernstein(
981
981
poly_coeffs.data(), poly_coeffs.size(), lowest_energy/1000.0, highest_energy/1000.0 );
982
982
983
+ assert( berstein_coeffs.size() == (num_fwhm_pars + 2) );
983
984
paramaters.resize( num_fwhm_pars );
984
985
for( size_t i = 0; i < berstein_coeffs.size(); ++i )
985
986
paramaters[i] = berstein_coeffs[i];
986
987
987
988
// Set energy range, in keV
988
- paramaters[berstein_coeffs.size() ] = lowest_energy;
989
- paramaters[berstein_coeffs.size() + 1] = highest_energy;
989
+ paramaters[num_fwhm_pars - 2 ] = lowest_energy;
990
+ paramaters[num_fwhm_pars - 1] = highest_energy;
990
991
break;
991
992
}
992
993
default:
@@ -1124,7 +1125,7 @@ std::shared_ptr<const DetectorPeakResponse> get_fwhm_coefficients( const RelActC
1124
1125
warnings.push_back( "Failed to refine FWHM fit from data: " + string(e.what()) + ". Will use initial estimate." );
1125
1126
}
1126
1127
}//if( filtered_peaks->size() != all_peaks.size() )
1127
-
1128
+
1128
1129
paramaters.resize( fwhm_paramatersf.size() );
1129
1130
for( size_t i = 0; i < fwhm_paramatersf.size(); ++i )
1130
1131
paramaters[i] = static_cast<double>( fwhm_paramatersf[i] );
@@ -1177,6 +1178,28 @@ std::shared_ptr<const DetectorPeakResponse> get_fwhm_coefficients( const RelActC
1177
1178
1178
1179
new_drf->setFwhmCoefficients( fwhm_pars_float, form_to_fit );
1179
1180
1181
+ switch( fwhm_form )
1182
+ {
1183
+ case RelActCalcAuto::FwhmForm::Berstein_2:
1184
+ case RelActCalcAuto::FwhmForm::Berstein_3:
1185
+ case RelActCalcAuto::FwhmForm::Berstein_4:
1186
+ case RelActCalcAuto::FwhmForm::Berstein_5:
1187
+ case RelActCalcAuto::FwhmForm::Berstein_6:
1188
+ {
1189
+ // Convert polynomial coefficients to Berstein - note that the power-series
1190
+ // representation uses MeV, while lowest_energy and highest_energy are in keV
1191
+ vector<double> poly_coeffs( begin(paramaters), end(paramaters) );
1192
+ paramaters = BersteinPolynomial::power_series_to_bernstein( poly_coeffs.data(), poly_coeffs.size(),
1193
+ lowest_energy/1000.0, highest_energy/1000.0 );
1194
+ paramaters.push_back( lowest_energy );
1195
+ paramaters.push_back( highest_energy );
1196
+ break;
1197
+ }
1198
+
1199
+ default:
1200
+ break;
1201
+ }//switch( fwhm_form )
1202
+
1180
1203
return new_drf;
1181
1204
};//get_fwhm_coefficients(...)
1182
1205
@@ -2524,31 +2547,6 @@ struct RelActAutoCostFcn /* : ROOT::Minuit2::FCNBase() */
2524
2547
constant_parameters.push_back( static_cast<int>(par_index) );
2525
2548
}
2526
2549
2527
- // For Berstein forms, mark the min/max energy parameters as constant (if not already marked)
2528
- switch( options.fwhm_form )
2529
- {
2530
- case RelActCalcAuto::FwhmForm::Berstein_2:
2531
- case RelActCalcAuto::FwhmForm::Berstein_3:
2532
- case RelActCalcAuto::FwhmForm::Berstein_4:
2533
- case RelActCalcAuto::FwhmForm::Berstein_5:
2534
- case RelActCalcAuto::FwhmForm::Berstein_6:
2535
- {
2536
- const size_t num_berstein_coeffs = starting_fwhm_paramaters.size() - 2;
2537
- const size_t min_energy_par_index = cost_functor->m_fwhm_par_start_index + num_berstein_coeffs;
2538
- const size_t max_energy_par_index = cost_functor->m_fwhm_par_start_index + num_berstein_coeffs + 1;
2539
-
2540
- // Only add if not already in constant_parameters (could also check `options.fwhm_estimation_method == RelActCalcAuto::FwhmEstimationMethod::FixedToAllPeaksInSpectrum` )
2541
- if( std::find( constant_parameters.begin(), constant_parameters.end(), static_cast<int>(min_energy_par_index) ) == constant_parameters.end() )
2542
- constant_parameters.push_back( static_cast<int>(min_energy_par_index) );
2543
-
2544
- if( std::find( constant_parameters.begin(), constant_parameters.end(), static_cast<int>(max_energy_par_index) ) == constant_parameters.end() )
2545
- constant_parameters.push_back( static_cast<int>(max_energy_par_index) );
2546
-
2547
- break;
2548
- }
2549
- default:
2550
- break;
2551
- }
2552
2550
2553
2551
// Set bounds for Berstein coefficients based on expected peak width limits
2554
2552
switch( options.fwhm_form )
@@ -2642,6 +2640,20 @@ struct RelActAutoCostFcn /* : ROOT::Minuit2::FCNBase() */
2642
2640
parameters[par_index] = std::max( parameters[par_index], lower_bounds[par_index].value() );
2643
2641
parameters[par_index] = std::min( parameters[par_index], upper_bounds[par_index].value() );
2644
2642
}//for( size_t i = 0; i < num_berstein_coeffs; ++i )
2643
+
2644
+ // For Berstein forms, mark the min/max energy parameters as constant (if not already marked)
2645
+ const int min_energy_par_index = static_cast<int>( cost_functor->m_fwhm_par_start_index + num_berstein_coeffs );
2646
+ const int max_energy_par_index = min_energy_par_index + 1;
2647
+ parameters[min_energy_par_index] = lowest_fwhm_energy;
2648
+ parameters[max_energy_par_index] = highest_fwhm_energy;
2649
+
2650
+ assert( starting_fwhm_paramaters[starting_fwhm_paramaters.size() - 2] == lowest_fwhm_energy );
2651
+ assert( starting_fwhm_paramaters[starting_fwhm_paramaters.size() - 1] == highest_fwhm_energy );
2652
+
2653
+ if( std::find( begin(constant_parameters), end(constant_parameters), min_energy_par_index ) == end(constant_parameters) )
2654
+ constant_parameters.push_back( min_energy_par_index );
2655
+ if( std::find( begin(constant_parameters), end(constant_parameters), max_energy_par_index ) == end(constant_parameters) )
2656
+ constant_parameters.push_back( max_energy_par_index );
2645
2657
2646
2658
break;
2647
2659
}//case Berstein
0 commit comments