@@ -2908,11 +2908,13 @@ struct RelActAutoCostFcn /* : ROOT::Minuit2::FCNBase() */
29082908 try
29092909 {
29102910 const double mf = manual_solution.mass_fraction( mass_frac_constraint->nuclide->symbol );
2911- double frac = (mf - mass_frac_constraint->lower_mass_fraction) / (mass_frac_constraint->upper_mass_fraction - mass_frac_constraint->lower_mass_fraction);
2911+ const double frac = (mf - mass_frac_constraint->lower_mass_fraction) / (mass_frac_constraint->upper_mass_fraction - mass_frac_constraint->lower_mass_fraction);
29122912 assert( frac > -0.0002 && frac < 1.0002 );
2913- frac = std::min( 1.0, std::max( frac, 0.0 ) );
2914- parameters[act_index] = RelActAutoCostFcn::sm_activity_par_offset + 0.5*frac;
2915- cerr << "\n\nStill having trouble navigating to global minima\n\nHacked mass fraction to be halfway in the range it should!\n\n" << endl;
2913+ const double clamped_frac = std::min( 1.0, std::max( frac, 0.0 ) );
2914+ parameters[act_index] = RelActAutoCostFcn::sm_activity_par_offset + 0.5*clamped_frac;
2915+
2916+ cerr << "\n\nStill having trouble navigating to global minima\n\nHacked mass fraction to be halfway in the range it should! - From " << frac << " to " << 0.5*clamped_frac << "\n\n" << endl;
2917+
29162918#pragma message("Still having trouble navigating to global minima for RelActAuto. Hacked mass fraction to be halfway in the range it should! - should undo this (but seems to help for some problems).")
29172919 }catch( std::exception & )
29182920 {
@@ -5952,7 +5954,7 @@ struct RelActAutoCostFcn /* : ROOT::Minuit2::FCNBase() */
59525954 // This is the same logic used in the other parts of the codebase
59535955 return (T(1.0) - corr_output.pu242_mass_frac) * nuc_rel_mass / pu_total_mass;
59545956 }//switch( nuclide->massNumber )
5955-
5957+
59565958 assert( 0 );
59575959 throw std::logic_error( "Failed to find expected Pu nuclide." );
59585960 return nuc_rel_mass / pu_total_mass;
@@ -10686,6 +10688,46 @@ std::ostream &RelActAutoSolution::print_summary( std::ostream &out ) const
1068610688 print_iso_line( "Pu241" );
1068710689 print_iso_line( "Pu242" );
1068810690 out << "\n";
10691+
10692+
10693+ /*
10694+ //Correct back to a specific age.
10695+ const SpecUtils::time_point_t meas_time = m_foreground->start_time();
10696+ const SpecUtils::time_point_t wanted_time = SpecUtils::time_from_string( "19880101", SpecUtils::DateParseEndianType::MiddleEndianFirst );
10697+ if( SpecUtils::is_special(meas_time) || SpecUtils::is_special(wanted_time) )
10698+ {
10699+ cerr << "Meas time (" << SpecUtils::to_iso_string(meas_time) << ") or wanted time (" << SpecUtils::to_iso_string(wanted_time) << ") is invalid." << endl;
10700+ }else
10701+ {
10702+ const double num_seconds_back_decay = 1.0*std::chrono::duration_cast<std::chrono::seconds>(meas_time - wanted_time).count();
10703+ const size_t rel_eff_index = 0;
10704+ const SandiaDecay::Nuclide * const pu238 = db->nuclide( "Pu238" );
10705+ const SandiaDecay::Nuclide * const pu239 = db->nuclide( "Pu239" );
10706+ const SandiaDecay::Nuclide * const pu240 = db->nuclide( "Pu240" );
10707+ const SandiaDecay::Nuclide * const pu241 = db->nuclide( "Pu241" );
10708+ const SandiaDecay::Nuclide * const pu242 = db->nuclide( "Pu242" );
10709+
10710+ assert( pu238 && pu239 && pu240 && pu241 && pu242 );
10711+
10712+ vector<tuple<const SandiaDecay::Nuclide *,double>> input_nuclide_rel_acts;
10713+ try{ input_nuclide_rel_acts.emplace_back( pu238, rel_activity(pu238, rel_eff_index) ); }catch(...){}
10714+ try{ input_nuclide_rel_acts.emplace_back( pu239, rel_activity(pu239, rel_eff_index) ); }catch(...){}
10715+ try{ input_nuclide_rel_acts.emplace_back( pu240, rel_activity(pu240, rel_eff_index) ); }catch(...){}
10716+ try{ input_nuclide_rel_acts.emplace_back( pu241, rel_activity(pu241, rel_eff_index) ); }catch(...){}
10717+ try{ input_nuclide_rel_acts.emplace_back( pu242, rel_activity(pu242, rel_eff_index) ); }catch(std::exception &e){
10718+ cerr << "Failed to get Pu242 act: " << e.what() << endl;
10719+ }
10720+
10721+ const vector<tuple<const SandiaDecay::Nuclide *,double,double>> wanted_time_vals
10722+ = RelActCalc::back_decay_relative_activities( num_seconds_back_decay, input_nuclide_rel_acts );
10723+ for( const tuple<const SandiaDecay::Nuclide *,double,double> &nuc_act_mass : wanted_time_vals )
10724+ {
10725+ const SandiaDecay::Nuclide * const nuc = get<0>(nuc_act_mass);
10726+ const double rel_mass = get<2>(nuc_act_mass);
10727+ cout << "Time corrected " << nuc->symbol << " rel mass to " << SpecUtils::to_iso_string(wanted_time) << " is " << (100.0*rel_mass) << "%" << endl;
10728+ }
10729+ }//if( correct from/to times okay ) / else
10730+ */
1068910731 }//if( pu_corr )
1069010732
1069110733
@@ -11507,12 +11549,14 @@ void RelActAutoSolution::print_html_report( std::ostream &out ) const
1150711549 //info.obs_eff_data = m_obs_eff_for_each_curve[rel_eff_index];
1150811550 if( rel_eff_index < m_obs_eff_for_each_curve.size() ) //`m_obs_eff_for_each_curve` may be empty if computation failed
1150911551 {
11510- // Filter to only include ObsEff entries with observed_efficiency > 0 and num_sigma_significance > 4
11511- for( const auto &obs_eff : m_obs_eff_for_each_curve[rel_eff_index] )
11512- {
11552+ // Filter to only include ObsEff entries with observed_efficiency > 0 and num_sigma_significance > 4, and
11553+ // having at least 5% of counts in ROI, and whose peak means+-1sigma are in the ROI.
11554+ for( const RelActCalcAuto::RelActAutoSolution::ObsEff &obs_eff : m_obs_eff_for_each_curve[rel_eff_index] )
11555+ {
1151311556 if( (obs_eff.observed_efficiency > 0.0)
1151411557 && (obs_eff.num_sigma_significance > 2.5)
11515- && (obs_eff.fraction_roi_counts > 0.05) )
11558+ && (obs_eff.fraction_roi_counts > 0.05)
11559+ && obs_eff.within_roi )
1151611560 {
1151711561 info.obs_eff_data.push_back( obs_eff );
1151811562 }
@@ -12404,7 +12448,6 @@ double RelActAutoSolution::rel_activity( const SrcVariant &src, const size_t rel
1240412448 if( rel_eff_index >= m_rel_activities.size() )
1240512449 throw std::logic_error( "rel_activity: invalid rel eff index" );
1240612450
12407- const size_t nuc_index = nuclide_index( src, rel_eff_index );
1240812451 const vector<NuclideRelAct> &nuclides = m_rel_activities[rel_eff_index];
1240912452
1241012453 // If Pu242, we will use the corrected mass ratio to Pu239 to get activity relative
@@ -12424,9 +12467,10 @@ double RelActAutoSolution::rel_activity( const SrcVariant &src, const size_t rel
1242412467 const double corr_rel_pu242_act = pu242->activityPerGram() * m_corrected_pu[rel_eff_index]->pu242_mass_frac;
1242512468
1242612469 const double raw_pu239_activity = m_rel_activities[rel_eff_index][nuclide_index(pu239,rel_eff_index)].rel_activity;
12427- return raw_pu239_activity * corr_rel_pu242_act / corr_rel_pu242_act ;
12470+ return raw_pu239_activity * corr_rel_pu242_act / corr_rel_pu239_act ;
1242812471 }//if( Pu242, and make correction )
1242912472
12473+ const size_t nuc_index = nuclide_index( src, rel_eff_index );
1243012474 return nuclides[nuc_index].rel_activity;
1243112475}//double rel_activity(...)
1243212476
@@ -13213,7 +13257,9 @@ std::vector<std::vector<RelActCalcAuto::RelActAutoSolution::ObsEff>>
1321313257
1321413258 eff.effective_sigma = effective_sigmas[i];
1321513259 eff.fraction_roi_counts = fit_amps[i] / total_roi_signal_counts;
13216-
13260+ eff.within_roi = (((effective_means[i] - eff.effective_sigma) >= roi.lower_energy)
13261+ && ((effective_means[i] + eff.effective_sigma) <= roi.upper_energy));
13262+
1321713263 //TODO: store peak indices better than `range_peak_indices` (its an artifact of prev code)
1321813264 for( const pair<size_t,size_t> &re_peak_ind : range_peak_indices )
1321913265 {
0 commit comments