Skip to content

Commit 16239b8

Browse files
committed
Add options to sum detectors together, for each sample number, and sum sample numbers together, for each detector.
1 parent f877057 commit 16239b8

File tree

1 file changed

+135
-1
lines changed

1 file changed

+135
-1
lines changed

src/CommandLineUtil.cpp

Lines changed: 135 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,7 @@ int run_command_util( const int argc, char *argv[] )
551551
bool no_background_spec, no_foreground_spec, no_intrinsic_spec;
552552
bool no_calibration_spec, no_unknown_spec;
553553
bool background_only, foreground_only, calibration_only, intrinsic_only;
554+
bool sum_det_per_sample, sum_samples_per_det;
554555
//bool spectra_of_likely_interest_only;
555556
vector<string> detector_renaimings, detectors_to_include, detectors_to_exclude;
556557

@@ -775,6 +776,14 @@ int run_command_util( const int argc, char *argv[] )
775776
"Ex., ./cambio --det-to-include=Aa1 input.n42 output.pcf\n\t"
776777
" ./cambio --det-to-include 'Aa 1' input.n42 output.pcf\n\t"
777778
)
779+
("sum-det-per-sample", po::value<bool>(&sum_det_per_sample)->default_value(false)->implicit_value(true),
780+
"For each sample number, sum all detectors for that sample number together.\n\t"
781+
"i.e. Output one spectrum for each sample, no matter how many detectors there are."
782+
)
783+
("sum-samples-per-det", po::value<bool>(&sum_samples_per_det)->default_value(false)->implicit_value(true),
784+
"For each detector, sum all sample numbers together.\n\t"
785+
"i.e. Output one spectrum for each detector, no matter how many sample is in input."
786+
)
778787
("combine-input-files", po::value<bool>(&combine_all_files)->default_value(false)->implicit_value(true),
779788
"Combines all input files, and writes a single output file."
780789
" An output file name must be specified.")
@@ -1465,12 +1474,21 @@ int run_command_util( const int argc, char *argv[] )
14651474
}
14661475
}//if( combine_all_files ) / else
14671476

1477+
if( sum_det_per_sample && sum_samples_per_det )
1478+
{
1479+
cerr << "You can not specify both 'sum-det-per-sample' and 'sum-samples-per-det'." << endl;
1480+
return 36;
1481+
}//if( sum_det_per_sample && sum_samples_per_det )
1482+
14681483

1484+
14691485

14701486
// We'll define a lambda to actually write the output file
14711487
auto write_output_file = [
14721488
//First we'll capture variables we wont change, by value
1473-
force_writing, summ_meas_for_single_out
1489+
force_writing, summ_meas_for_single_out,
1490+
sum_det_per_sample,
1491+
sum_samples_per_det
14741492
#if( SpecUtils_ENABLE_D3_CHART )
14751493
, html_to_include
14761494
#endif
@@ -1485,6 +1503,122 @@ int run_command_util( const int argc, char *argv[] )
14851503
bool file_existed = false;
14861504
bool opened_all_output_files = true, encoded_all_files = true;
14871505

1506+
1507+
if( sum_det_per_sample )
1508+
{
1509+
const set<int> orig_samples = info.sample_numbers();
1510+
const vector<string> orig_dets = info.detector_names();
1511+
1512+
vector<shared_ptr<SpecUtils::Measurement>> keepers;
1513+
for( const int sample : orig_samples )
1514+
{
1515+
vector<shared_ptr<const SpecUtils::Measurement>> sample_meass = info.sample_measurements(sample);
1516+
if( sample_meass.size() == 1 )
1517+
{
1518+
auto m = make_shared<SpecUtils::Measurement>( *(sample_meass[0]) );
1519+
m->set_detector_name( "summed" );
1520+
keepers.push_back( m );
1521+
}else if( sample_meass.size() > 1 )
1522+
{
1523+
// TODO: summing will fail if we dont have any Measurements with gamma spectra that have valid energy calibrations (e.g., all Measurements are neutrons) - we should handle this case
1524+
try
1525+
{
1526+
shared_ptr<SpecUtils::Measurement> m = info.sum_measurements( {sample}, orig_dets, 0 );
1527+
1528+
set<string> titles;
1529+
bool all_background = true;
1530+
for( auto orig : sample_meass )
1531+
{
1532+
const bool empty_title = orig->title().empty();
1533+
if( !empty_title )
1534+
titles.insert( orig->title() );
1535+
1536+
all_background &= (SpecUtils::icontains( orig->title(), "Background")
1537+
|| (orig->source_type() == SpecUtils::SourceType::Background)
1538+
|| (info.passthrough() && (orig->occupied() == SpecUtils::OccupancyStatus::NotOccupied)));
1539+
}//for( auto orig : sample_meass )
1540+
1541+
assert( m );
1542+
if( m )
1543+
{
1544+
m->set_detector_name( "summed" );
1545+
m->set_sample_number( sample );
1546+
1547+
if( titles.size() == 1 )
1548+
m->set_title( *begin(titles) );
1549+
else if( all_background )
1550+
m->set_title( "Background" );
1551+
else
1552+
m->set_title( "" );
1553+
1554+
keepers.push_back( m );
1555+
}//if( m )
1556+
}catch( std::exception & )
1557+
{
1558+
cerr << "Error summing records for sample " << sample << " - omitting the "
1559+
<< sample_meass.size() << " records for this sample number." << endl;
1560+
}//try / catch - to sum the measurements for this sample
1561+
}//for( const int sample : orig_samples )
1562+
}//for( const int sample : orig_samples )
1563+
1564+
info.remove_measurements( info.measurements() );
1565+
for( auto m : keepers )
1566+
info.add_measurement( m, false );
1567+
1568+
info.set_uuid( "" );
1569+
info.cleanup_after_load( SpecUtils::SpecFile::CleanupAfterLoadFlags::DontChangeOrReorderSamples );
1570+
}//if( sum_det_per_sample )
1571+
1572+
1573+
if( sum_samples_per_det )
1574+
{
1575+
const set<int> orig_samples = info.sample_numbers();
1576+
const vector<string> orig_dets = info.detector_names();
1577+
1578+
vector<shared_ptr<SpecUtils::Measurement>> keepers;
1579+
map<string,vector<shared_ptr<const SpecUtils::Measurement>>> detector_to_meas;
1580+
map<string,shared_ptr<SpecUtils::Measurement>> detector_to_sum;
1581+
1582+
for( const string &det : orig_dets )
1583+
{
1584+
vector<shared_ptr<const SpecUtils::Measurement>> &det_meas = detector_to_meas[det];
1585+
for( const int sample : orig_samples )
1586+
{
1587+
auto m = info.measurement( sample, det );
1588+
if( m )
1589+
det_meas.push_back( m );
1590+
}//for( const int sample : orig_samples )
1591+
1592+
if( det_meas.size() == 1 )
1593+
{
1594+
auto m = make_shared<SpecUtils::Measurement>( *det_meas.front() );
1595+
m->set_sample_number( 1 );
1596+
keepers.push_back( m );
1597+
}else if( det_meas.size() > 1 )
1598+
{
1599+
// TODO: summing will fail if we dont have any Measurements with gamma spectra that have valid energy calibrations (e.g., this is a neutron detector) - we should handle this case
1600+
try
1601+
{
1602+
shared_ptr<SpecUtils::Measurement> m = info.sum_measurements( orig_samples, {det}, 0 );
1603+
m->set_detector_name( det );
1604+
m->set_sample_number( 1 );
1605+
keepers.push_back( m );
1606+
}catch( std::exception & )
1607+
{
1608+
cerr << "Error summing records for detector '" << det << "' - omitting the "
1609+
<< orig_samples.size() << " records for this detector." << endl;
1610+
}//try / catch - to sum the measurements for this sample
1611+
}//if( det_meas.size() == 1 ) / else 2 or more detectors
1612+
}//for( const string &det : orig_dets )
1613+
1614+
info.remove_measurements( info.measurements() );
1615+
for( auto m : keepers )
1616+
info.add_measurement( m, false );
1617+
1618+
info.set_uuid( "" );
1619+
info.cleanup_after_load( SpecUtils::SpecFile::CleanupAfterLoadFlags::DontChangeOrReorderSamples );
1620+
}//if( sum_samples_per_det )
1621+
14881622
if( format == SpecUtils::SaveSpectrumAsType::Chn
14891623
|| format == SpecUtils::SaveSpectrumAsType::SpcBinaryInt
14901624
|| format == SpecUtils::SaveSpectrumAsType::SpcBinaryFloat

0 commit comments

Comments
 (0)