@@ -584,6 +584,17 @@ bool loadFromUri_wrapper(SpecUtils::SpecFile* info, py::object pystream) {
584584 l.append ( p );
585585 return l;
586586 }
587+
588+ py::list meas_cal_coefficients_wrapper ( const SpecUtils::Measurement *meas )
589+ {
590+ py::list l;
591+ if ( !meas )
592+ return l;
593+
594+ for ( const float p : meas->calibration_coeffs () )
595+ l.append ( static_cast <double >(p) );
596+ return l;
597+ }
587598
588599 py::list gamma_counts_wrapper ( const SpecUtils::Measurement *meas )
589600 {
@@ -979,6 +990,29 @@ bool loadFromUri_wrapper(SpecUtils::SpecFile* info, py::object pystream) {
979990 info->set_parse_warnings ( remarks );
980991 }
981992
993+ py::list cal_channel_energies_wrapper ( const SpecUtils::EnergyCalibration *cal )
994+ {
995+ py::list l;
996+ if ( !cal || !cal->channel_energies () )
997+ return l;
998+
999+ for ( auto p : *cal->channel_energies () )
1000+ l.append ( p );
1001+ return l;
1002+ }
1003+
1004+ py::list cal_coefficients_wrapper ( const SpecUtils::EnergyCalibration *cal )
1005+ {
1006+ py::list l;
1007+ if ( !cal )
1008+ return l;
1009+
1010+ for ( const float p : cal->coefficients () )
1011+ l.append ( static_cast <double >(p) );
1012+ return l;
1013+ }
1014+
1015+
9821016std::shared_ptr<SpecUtils::EnergyCalibration> energyCalFromPolynomial_wrapper ( const size_t num_channels,
9831017 py::list py_coefs )
9841018{
@@ -1058,7 +1092,70 @@ std::shared_ptr<SpecUtils::EnergyCalibration> energyCalFromLowerChannelEnergies_
10581092 cal->set_lower_channel_energy ( num_channels, energies );
10591093 return cal;
10601094}
1095+
1096+ py::list polynomial_coef_to_fullrangefraction_wrapper ( py::list py_coefs, const size_t nchannel )
1097+ {
1098+ vector<float > coefs;
1099+ size_t n = py_coefs.size ();
1100+ for ( size_t i = 0 ; i < n; ++i )
1101+ coefs.push_back ( py::cast<float >( py_coefs[i] ) );
1102+
1103+ const vector<float > frf_coefs = SpecUtils::polynomial_coef_to_fullrangefraction ( coefs, nchannel );
1104+
1105+ py::list answer;
1106+ for ( const float p : frf_coefs )
1107+ answer.append ( static_cast <double >(p) );
1108+ return answer;
1109+ }
1110+
1111+ py::list fullrangefraction_coef_to_polynomial_wrapper ( py::list py_coefs, const size_t nchannel )
1112+ {
1113+ vector<float > coefs;
1114+ size_t n = py_coefs.size ();
1115+ for ( size_t i = 0 ; i < n; ++i )
1116+ coefs.push_back ( py::cast<float >( py_coefs[i] ) );
10611117
1118+ const vector<float > poly_coefs = SpecUtils::fullrangefraction_coef_to_polynomial ( coefs, nchannel );
1119+
1120+ py::list answer;
1121+ for ( const float p : poly_coefs )
1122+ answer.append ( static_cast <double >(p) );
1123+ return answer;
1124+ }
1125+
1126+
1127+ py::list mid_channel_polynomial_to_fullrangeFraction_wrapper ( py::list py_coefs, const size_t nchannel )
1128+ {
1129+ vector<float > coefs;
1130+ size_t n = py_coefs.size ();
1131+ for ( size_t i = 0 ; i < n; ++i )
1132+ coefs.push_back ( py::cast<float >( py_coefs[i] ) );
1133+
1134+ const vector<float > frf_coefs = SpecUtils::mid_channel_polynomial_to_fullrangeFraction ( coefs, nchannel );
1135+
1136+ py::list answer;
1137+ for ( const float p : frf_coefs )
1138+ answer.append ( static_cast <double >(p) );
1139+ return answer;
1140+ }
1141+
1142+ py::list mid_channel_polynomial_to_lower_channel_energy_poly_wrapper ( py::list py_coefs, const size_t nchannel )
1143+ {
1144+ vector<float > coefs;
1145+ size_t n = py_coefs.size ();
1146+ for ( size_t i = 0 ; i < n; ++i )
1147+ coefs.push_back ( py::cast<float >( py_coefs[i] ) );
1148+
1149+ const vector<float > frf_coefs = SpecUtils::mid_channel_polynomial_to_fullrangeFraction ( coefs, nchannel );
1150+ const vector<float > poly_coefs = SpecUtils::fullrangefraction_coef_to_polynomial ( frf_coefs, nchannel );
1151+
1152+ py::list answer;
1153+ for ( const float p : poly_coefs )
1154+ answer.append ( static_cast <double >(p) );
1155+ return answer;
1156+ }
1157+
1158+
10621159
10631160#if ( SpecUtils_ENABLE_D3_CHART )
10641161bool write_spectrum_data_js_wrapper ( py::object pystream,
@@ -1370,12 +1467,11 @@ py::class_<SpecUtils::EnergyCalibration>(m, "EnergyCalibration")
13701467 " Returns the energy calibration type" )
13711468 .def ( " valid" , &SpecUtils::EnergyCalibration::valid,
13721469 " Returns if the energy calibration is valid." )
1373- .def ( " coefficients" , &SpecUtils::EnergyCalibration::coefficients, py::rv_policy::reference_internal ,
1374- " Returns the list of energy calibration coeficients .\n "
1470+ .def ( " coefficients" , &cal_coefficients_wrapper ,
1471+ " Returns the list of energy calibration coefficients .\n "
13751472 " Will only be empty for SpecUtils.EnergyCalType.InvalidEquationType." )
1376- // TODO: I think we should put a wrapper around channel_energies, and return a proper python list
1377- .def ( " channelEnergies" , &SpecUtils::EnergyCalibration::channel_energies, py::rv_policy::reference_internal,
1378- " Returns lower channel energies; will have one more entry than the number of channels." )
1473+ .def ( " channelEnergies" , &cal_channel_energies_wrapper,
1474+ " Returns lower channel energies; will have one more entry than the number of channels." )
13791475 .def ( " deviationPairs" , &SpecUtils::EnergyCalibration::deviation_pairs, py::rv_policy::reference_internal )
13801476 .def ( " numChannels" , &SpecUtils::EnergyCalibration::num_channels,
13811477 " Returns the number of channels this energy calibration is for." )
@@ -1388,32 +1484,66 @@ py::class_<SpecUtils::EnergyCalibration>(m, "EnergyCalibration")
13881484 .def ( " upperEnergy" , &SpecUtils::EnergyCalibration::upper_energy,
13891485 " Returns highest energy of this energy calibration." )
13901486 .def ( " setPolynomial" , &SpecUtils::EnergyCalibration::set_polynomial,
1391- " NumChannels" _a, " Coeffiecients " _a, " DeviationPairs" _a,
1392- " Sets the energy calibration information from Polynomial defined coefficents ." )
1487+ " NumChannels" _a, " Coefficients " _a, " DeviationPairs" _a,
1488+ " Sets the energy calibration information from Polynomial defined coefficients ." )
13931489 .def ( " setFullRangeFraction" , &SpecUtils::EnergyCalibration::set_full_range_fraction,
1394- " NumChannels" _a, " Coeffiecients " _a, " DeviationPairs" _a,
1395- " Sets the energy calibration information from Full Range Fraction (e.g., what PCF files use) defined coefficents ." )
1490+ " NumChannels" _a, " Coefficients " _a, " DeviationPairs" _a,
1491+ " Sets the energy calibration information from Full Range Fraction (e.g., what PCF files use) defined coefficients ." )
13961492 .def ( " setLowerChannelEnergy" , set_lower_channel_energy_fcn_ptr,
13971493 " NumChannels" _a, " Energies" _a,
13981494 " Sets the energy calibration information from lower channel energies." )
13991495 .def_static ( " fromPolynomial" , &energyCalFromPolynomial_wrapper,
1400- " NumChannels" _a, " Coeffiecients " _a,
1496+ " NumChannels" _a, " Coefficients " _a,
14011497 " Creates a new energy calibration object from a polynomial definition." )
14021498 .def_static ( " fromPolynomial" , &energyCalFromPolynomial_2_wrapper,
1403- " NumChannels" _a, " Coeffiecients " _a, " DeviationPairs" _a,
1499+ " NumChannels" _a, " Coefficients " _a, " DeviationPairs" _a,
14041500 " Creates a new energy calibration object from a polynomial definition, with some nonlinear-deviation pairs." )
14051501 .def_static ( " fromFullRangeFraction" , &energyCalFromFullRangeFraction_wrapper,
1406- " NumChannels" _a, " Coeffiecients " _a,
1502+ " NumChannels" _a, " Coefficients " _a,
14071503 " Creates a new energy calibration object from a Full Range Fraction definition." )
14081504 .def_static ( " fromFullRangeFraction" , &energyCalFromFullRangeFraction_2_wrapper,
1409- " NumChannels" _a, " Coeffiecients " _a, " DeviationPairs" _a,
1505+ " NumChannels" _a, " Coefficients " _a, " DeviationPairs" _a,
14101506 " Creates a new energy calibration object from a Full Range Fraction definition, with some nonlinear-deviation pairs." )
14111507 .def_static ( " fromLowerChannelEnergies" , &energyCalFromLowerChannelEnergies_wrapper,
14121508 " NumChannels" _a, " Energies" _a,
14131509 " Creates a new energy calibration object from a lower channel energies." )
14141510;
14151511
14161512
1513+ m.def (" polynomialCoefToFullRangeFraction" ,
1514+ &polynomial_coef_to_fullrangefraction_wrapper,
1515+ " coeffs" _a, " nchannel" _a,
1516+ " Converts from polynomial energy calibration coefficients, to Full Range Fraction coefficients."
1517+ " Only works for up to the first four coefficients, as the fifth"
1518+ " one for FRF does not translate easily to polynomial, so it will be ignored if"
1519+ " present."
1520+ ).def (" fullRangeFractionCoefToPolynomial" ,
1521+ &fullrangefraction_coef_to_polynomial_wrapper,
1522+ " coeffs" _a, " nchannel" _a,
1523+ " Converts from Full Range Fraction energy calibration coefficients, to polynomial coefficients."
1524+ " Only works for up to the first four coefficients, as the fifth"
1525+ " one for FRF does not translate easily to polynomial, so it will be ignored if"
1526+ " present."
1527+ )
1528+ .def (" MidChannelPolynomialToFullRangeFraction" ,
1529+ &mid_channel_polynomial_to_fullrangeFraction_wrapper,
1530+ " coeffs" _a, " nchannel" _a,
1531+ " Converts coefficients from polynomial equation that uses the convention"
1532+ " the energy given by the equation is the middle of the channel (which is"
1533+ " non-standard) to standard full range fraction equation coefficients.\n "
1534+ " Only considers up to the first four coefficients."
1535+ ).def (" MidChannelPolynomialToLowerEdgePolynomial" ,
1536+ &mid_channel_polynomial_to_lower_channel_energy_poly_wrapper,
1537+ " coeffs" _a, " nchannel" _a,
1538+ " Converts coefficients from polynomial equation that uses the convention"
1539+ " the energy given by the equation is the middle of the channel (which is"
1540+ " non-standard) to standard polynomial equation coefficients that give"
1541+ " lower energy of each channel.\n "
1542+ " Only considers up to the first four coefficients."
1543+ );
1544+
1545+
1546+
14171547 {// begin Measurement class scope
14181548 py::class_<SpecUtils::Measurement>(m, " Measurement" )
14191549 // .def(py::new_([](){ return make_shared<SpecUtils::Measurement>();}))
@@ -1439,7 +1569,7 @@ py::class_<SpecUtils::EnergyCalibration>(m, "EnergyCalibration")
14391569 .def ( " energyCalibrationModel" , &SpecUtils::Measurement::energy_calibration_model )
14401570 .def ( " remarks" , &measurement_remarks_wrapper )
14411571 .def ( " startTime" , &start_time_wrapper )
1442- .def ( " calibrationCoeffs" , &SpecUtils::Measurement::calibration_coeffs, py::rv_policy::reference )
1572+ .def ( " calibrationCoeffs" , &meas_cal_coefficients_wrapper )
14431573 .def ( " deviationPairs" , &SpecUtils::Measurement::deviation_pairs, py::rv_policy::reference )
14441574 .def ( " channelEnergies" , &channel_energies_wrapper )
14451575 .def ( " gammaCounts" , &gamma_counts_wrapper )
0 commit comments