Skip to content

Commit 6285905

Browse files
committed
Fixup some issues with background/secondary peaks.
The D3SpectrumDisplayDiv was displaying the primary spectrum instance background peaks for any instance of D3SpectrumDisplayDiv. Moved to having the PeakModel also track background/secondary peaks, but in a very limited way - you can only set all the peaks for background/secondary - which triggers a single signal that these peaks were changed - not the granularity that the foreground offers. So now D3SpectrumDisplayDiv uses the PeakModel to track and get the background/secondary peaks.
1 parent c718078 commit 6285905

12 files changed

+303
-148
lines changed

InterSpec/InterSpec.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,10 @@ class InterSpec : public Wt::WContainerWidget
383383
const SpecUtils::SpectrumType spec_type,
384384
const std::string &ref_line_name = "" );
385385

386-
/** Sets the peaks for the given spectrum. If foreground, you should consider instead to use the PeakModel.
386+
/** Sets the peaks for the given spectrum - taking care of adding a undo/redo step.
387+
388+
If you do not wish to add a undo/redo step, you can call `PeakModel::setPeaks(peaks,SpectrumType).`
389+
(the undo/redo is the only differnce between calling this function and the PeakModel function directly).
387390
388391
@param spectrum Which spectrum to set the peaks for.
389392
@param peaks The peaks to set. Must not be nullptr, or the currently set deque of peaks.

InterSpec/PeakModel.h

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,11 @@
4040

4141
class SpecMeas;
4242

43-
namespace SpecUtils{ class Measurement; }
43+
namespace SpecUtils
44+
{
45+
class Measurement;
46+
enum class SpectrumType : int;
47+
}
4448

4549
namespace SandiaDecay
4650
{
@@ -60,6 +64,9 @@ class PeakModel: public Wt::WAbstractItemModel
6064
That is, the row specifies the peak, and the column represents
6165
various peak values, as specified by the 'Columns' enum.
6266
67+
All functions refer to the foreground, except `peaks(SpectrumType)` and `measurement(SpectrumType)` - which just returns what
68+
`setPeakFromSpecMeas(...)` was last called for the type (currently only the main InterSpec class do anything other than for foreground).
69+
6370
Incomplete TODO list:
6471
- add a `replacePeaks(orig,newer)` function to allow updating peak quanitites in one step
6572
- Or allow setting kLowerX/kUpperX columns in setData(...) function
@@ -98,7 +105,8 @@ class PeakModel: public Wt::WAbstractItemModel
98105
// or the displayed sample numbers), then this function should be called to
99106
// update the m_peaks pointer to be from the appropriate SpecMeas object.
100107
void setPeakFromSpecMeas( std::shared_ptr<SpecMeas> meas,
101-
const std::set<int> &samplenums );
108+
const std::set<int> &samplenums,
109+
const SpecUtils::SpectrumType specType );
102110

103111
/** Normally we keep the peaks added/removed up to date with the #SpecMeas passed into
104112
#setPeakFromSpecMeas (i.e., the #SpecMeas "owns" the peaks), but if you dont want to do
@@ -141,6 +149,26 @@ class PeakModel: public Wt::WAbstractItemModel
141149

142150
const std::deque<std::shared_ptr<const PeakDef>> &sortedPeaks() const;
143151

152+
/** Get the currently set peaks - this requires that `setPeakFromSpecMeas(spec, samples, type)`
153+
has been called to set these - currently the only place that does this for anything besides the foreground is the main InterSpec class.
154+
155+
All other functions in this class refer to foreground peaks, except `peaks(SpectrumType)` and `measurement(SpectrumType)`.
156+
*/
157+
std::shared_ptr<const std::deque<std::shared_ptr<const PeakDef>>> peaks( const SpecUtils::SpectrumType type ) const;
158+
159+
std::weak_ptr<SpecMeas> measurement( const SpecUtils::SpectrumType type );
160+
161+
Wt::Signal<> &backgroundPeaksChanged();
162+
Wt::Signal<> &secondaryPeaksChanged();
163+
164+
165+
/** Get the currently set secondary peaks - this requires that `setPeakFromSpecMeas(back, backSamples, SpectrumType::SecondaryForeground)`
166+
has been called to set these - currently the only place that does this is the main InterSpec class.
167+
168+
All other functions in this class refer to foregorund peaks, except `backgroundPeaks()` and `secondaryPeaks()`.
169+
*/
170+
std::shared_ptr<const std::deque<std::shared_ptr<const PeakDef>>> secondaryPeaks() const;
171+
144172
//definePeakXRangeAndChi2(...): Inorder to save cpu (and mostly memorry access
145173
// time) later on, this function will define the lower and upper energy range
146174
// of peaks that have a polynomial continum defined, and have not already had
@@ -176,6 +204,9 @@ class PeakModel: public Wt::WAbstractItemModel
176204
*/
177205
void setPeaks( std::vector<std::shared_ptr<const PeakDef>> peaks );
178206

207+
208+
void setPeaks( const std::deque<std::shared_ptr<const PeakDef>> &peakdeque, const SpecUtils::SpectrumType type );
209+
179210
//removePeak( size_t ): removes the specified `peakn`, where the peakn refers
180211
// to the peak at position `peakn` when sorted by peak means (similar
181212
// behavior as all other functions which refer to peaks by index).
@@ -439,8 +470,16 @@ class PeakModel: public Wt::WAbstractItemModel
439470

440471
//Peaks are stored sorted according to peak.mean, since some of the algorithms
441472
// that work on the peaks need them to be sorted by mean
442-
std::shared_ptr< std::deque< PeakShrdPtr > > m_peaks;
443-
std::weak_ptr<SpecMeas> m_measurment;
473+
std::shared_ptr< std::deque< std::shared_ptr<const PeakDef> > > m_peaks;
474+
std::weak_ptr<SpecMeas> m_measurment; //Foreground
475+
476+
std::shared_ptr<std::deque<std::shared_ptr<const PeakDef>>> m_background_peaks;
477+
std::weak_ptr<SpecMeas> m_background;
478+
Wt::Signal<> m_backgroundPeaksChanged;
479+
480+
std::shared_ptr<std::deque<std::shared_ptr<const PeakDef>>> m_secondary_peaks;
481+
std::weak_ptr<SpecMeas> m_secondary;
482+
Wt::Signal<> m_secondaryPeaksChanged;
444483

445484
Columns m_sortColumn;
446485
Wt::SortOrder m_sortOrder;

src/D3SpectrumDisplayDiv.cpp

Lines changed: 46 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,8 @@ void D3SpectrumDisplayDiv::setPeakModel( PeakModel *model )
551551
m_peakModel->rowsInserted().connect( boost::bind(&D3SpectrumDisplayDiv::schedulePeakRedraw, this, SpecUtils::SpectrumType::Foreground) );
552552
m_peakModel->layoutChanged().connect( boost::bind(&D3SpectrumDisplayDiv::schedulePeakRedraw, this, SpecUtils::SpectrumType::Foreground) );
553553
m_peakModel->modelReset().connect( boost::bind(&D3SpectrumDisplayDiv::schedulePeakRedraw, this, SpecUtils::SpectrumType::Foreground) );
554+
m_peakModel->backgroundPeaksChanged().connect( boost::bind(&D3SpectrumDisplayDiv::schedulePeakRedraw, this, SpecUtils::SpectrumType::Background) );
555+
m_peakModel->secondaryPeaksChanged().connect( boost::bind(&D3SpectrumDisplayDiv::schedulePeakRedraw, this, SpecUtils::SpectrumType::SecondForeground) );
554556
}//void setPeakModel( PeakModel *model );
555557

556558

@@ -1374,7 +1376,7 @@ void D3SpectrumDisplayDiv::setForegroundPeaksToClient()
13741376
13751377
if( m_peakModel )
13761378
{
1377-
std::shared_ptr<const std::deque< PeakModel::PeakShrdPtr > > peaks = m_peakModel->peaks();
1379+
std::shared_ptr<const std::deque<shared_ptr<const PeakDef>> > peaks = m_peakModel->peaks();
13781380
if( peaks )
13791381
{
13801382
vector< std::shared_ptr<const PeakDef> > inpeaks( peaks->begin(), peaks->end() );
@@ -1435,33 +1437,13 @@ void D3SpectrumDisplayDiv::setPeaksToClient( const SpecUtils::SpectrumType spect
14351437
}//if( m_defaultPeakColor.isDefault() )
14361438

14371439

1438-
if( spectrum_type == SpecUtils::SpectrumType::Foreground )
1440+
shared_ptr<const deque<shared_ptr<const PeakDef>>> peaks = m_peakModel ? m_peakModel->peaks(spectrum_type) : nullptr;
1441+
if( peaks )
14391442
{
1440-
shared_ptr<const deque< PeakModel::PeakShrdPtr > > peaks = m_peakModel ? m_peakModel->peaks() : nullptr;
1441-
if( peaks )
1442-
{
1443-
vector< std::shared_ptr<const PeakDef> > inpeaks( peaks->begin(), peaks->end() );
1444-
const std::shared_ptr<const Measurement> &foreground = m_foreground;
1445-
const WColor peak_color = m_defaultPeakColor.isDefault() ? WColor(0, 51, 255) : m_defaultPeakColor;
1446-
js = PeakDef::peak_json( inpeaks, foreground, peak_color, 255 );
1447-
}
1448-
}else if( InterSpec *viewer = InterSpec::instance() )
1449-
{
1450-
// This is totally not correct - the spectrum may not be the main InterSpec spectrum
1451-
std::shared_ptr<SpecMeas> meas = viewer->measurment( spectrum_type );
1452-
const std::set<int> &samples = viewer->displayedSamples( spectrum_type );
1453-
1454-
if( meas && !samples.empty() )
1455-
{
1456-
std::shared_ptr<const std::deque< std::shared_ptr<const PeakDef> > > peaks = meas->peaks( samples );
1457-
if( peaks )
1458-
{
1459-
vector< std::shared_ptr<const PeakDef> > inpeaks( peaks->begin(), peaks->end() );
1460-
const WColor peak_color = m_defaultPeakColor.isDefault() ? WColor(0, 51, 255) : m_defaultPeakColor;
1461-
js = PeakDef::peak_json( inpeaks, spectrum_measurement, peak_color, alpha );
1462-
}
1463-
}
1464-
}//if( spectrum_type == SpecUtils::SpectrumType::Foreground ) / else
1443+
vector< std::shared_ptr<const PeakDef> > inpeaks( peaks->begin(), peaks->end() );
1444+
const WColor peak_color = m_defaultPeakColor.isDefault() ? WColor(0, 51, 255) : m_defaultPeakColor;
1445+
js = PeakDef::peak_json( inpeaks, spectrum_measurement, peak_color, alpha );
1446+
}
14651447

14661448
if( js.empty() )
14671449
js = "[]";
@@ -1913,8 +1895,8 @@ void D3SpectrumDisplayDiv::renderForegroundToClient()
19131895
// Set the peak data for the spectrum
19141896
if ( m_peakModel )
19151897
{
1916-
std::shared_ptr<const std::deque< PeakModel::PeakShrdPtr > > peaks = m_peakModel->peaks();
1917-
vector< std::shared_ptr<const PeakDef> > inpeaks;
1898+
shared_ptr<const deque<shared_ptr<const PeakDef>>> peaks = m_peakModel->peaks();
1899+
vector<shared_ptr<const PeakDef>> inpeaks;
19181900
if( peaks )
19191901
inpeaks.insert( end(inpeaks), peaks->begin(), peaks->end() );
19201902

@@ -2556,51 +2538,26 @@ void D3SpectrumDisplayDiv::performExistingRoiEdgeDragWork( double new_lower_ener
25562538
std::string spectrum_type,
25572539
bool isfinal )
25582540
{
2559-
std::unique_ptr<UndoRedoManager::PeakModelChange> peak_undo_creator;
2541+
assert( m_peakModel );
2542+
if( !m_peakModel )
2543+
return;
25602544

2561-
PeakModel *peakModel = nullptr;
2562-
shared_ptr<const Measurement> spectrum;
2563-
shared_ptr<const deque<PeakModel::PeakShrdPtr>> origpeaks;
2564-
shared_ptr<deque<PeakModel::PeakShrdPtr>> final_mondified_peaks;
2545+
std::unique_ptr<UndoRedoManager::PeakModelChange> peak_undo_creator;
2546+
if( isfinal )
2547+
peak_undo_creator.reset( new UndoRedoManager::PeakModelChange() );
25652548

25662549
const bool for_background = (spectrum_type == "BACKGROUND");
25672550
const bool for_secondary = (!for_background && (spectrum_type == "SECONDARY"));
2568-
SpecUtils::SpectrumType spec_type = SpecUtils::SpectrumType::Foreground;
2551+
assert( for_background || for_secondary || (spectrum_type == "FOREGROUND") );
2552+
const SpecUtils::SpectrumType spec_type = for_background ? SpecUtils::SpectrumType::Background
2553+
: (for_secondary ? SpecUtils::SpectrumType::SecondForeground : SpecUtils::SpectrumType::Foreground);
2554+
shared_ptr<const Measurement> spectrum = for_background ? m_background : (for_secondary ? m_secondary : m_foreground);
2555+
const shared_ptr<const deque<shared_ptr<const PeakDef>>> origpeaks = m_peakModel->peaks(spec_type);
2556+
2557+
shared_ptr<deque<shared_ptr<const PeakDef>>> final_mondified_peaks;
2558+
if( (for_background || for_secondary) && isfinal && origpeaks )
2559+
final_mondified_peaks = make_shared<deque<shared_ptr<const PeakDef>>>( begin(*origpeaks), end(*origpeaks) );
25692560

2570-
if( for_background || for_secondary )
2571-
{
2572-
spectrum = for_background ? m_background : m_secondary;
2573-
spec_type = for_background ? SpecUtils::SpectrumType::Background : SpecUtils::SpectrumType::SecondForeground;
2574-
2575-
InterSpec *viewer = InterSpec::instance();
2576-
assert( viewer );
2577-
if( !viewer )
2578-
return;
2579-
2580-
shared_ptr<SpecMeas> meas = viewer->measurment( spec_type );
2581-
const set<int> &samples = viewer->displayedSamples( spec_type );
2582-
origpeaks = (meas && !samples.empty()) ? meas->peaks( samples ) : nullptr;
2583-
2584-
if( isfinal && origpeaks )
2585-
final_mondified_peaks = make_shared<deque<PeakModel::PeakShrdPtr>>( begin(*origpeaks), end(*origpeaks) );
2586-
}else
2587-
{
2588-
assert( spectrum_type == "FOREGROUND" );
2589-
2590-
spec_type = SpecUtils::SpectrumType::Foreground;
2591-
spectrum = m_foreground;
2592-
peakModel = m_peakModel;
2593-
origpeaks = peakModel ? peakModel->peaks() : nullptr;
2594-
2595-
if( isfinal )
2596-
peak_undo_creator.reset( new UndoRedoManager::PeakModelChange() );
2597-
2598-
2599-
assert( peakModel );
2600-
if( !peakModel )
2601-
return;
2602-
}//if( background or secondary ) / else ( assume foreground )
2603-
26042561
assert( origpeaks && spectrum );
26052562
if( !origpeaks || !spectrum ) //Shouldnt ever happen
26062563
return;
@@ -2684,7 +2641,7 @@ void D3SpectrumDisplayDiv::performExistingRoiEdgeDragWork( double new_lower_ener
26842641
{
26852642
assert( final_mondified_peaks );
26862643
final_mondified_peaks->erase( std::remove_if( begin(*final_mondified_peaks), end(*final_mondified_peaks),
2687-
[&continuum]( const PeakModel::PeakShrdPtr &ptr ){
2644+
[&continuum]( const shared_ptr<const PeakDef> &ptr ){
26882645
return (continuum == ptr->continuum());
26892646
}), end(*final_mondified_peaks) );
26902647
}//if( isfinal && (for_background || for_secondary) )
@@ -2699,18 +2656,18 @@ void D3SpectrumDisplayDiv::performExistingRoiEdgeDragWork( double new_lower_ener
26992656
{
27002657
final_mondified_peaks->insert( end(*final_mondified_peaks), begin(new_roi_initial_peaks), end(new_roi_initial_peaks) );
27012658
std::sort( begin(*final_mondified_peaks), end(*final_mondified_peaks), &PeakDef::lessThanByMeanShrdPtr );
2702-
InterSpec::instance()->setPeaks( spec_type, final_mondified_peaks );
2659+
m_peakModel->setPeaks( *final_mondified_peaks, spec_type );
27032660
}else
27042661
{
2705-
assert( peakModel );
2662+
assert( m_peakModel );
27062663
// TODO: add a `PeakModel::replacePeaks(orig,newer)` function to allow updating peak quanitites in one step, or allow setting kLowerX/kUpperX columns in setData(...) function
2707-
peakModel->removePeaks( orig_roi_peaks );
2664+
m_peakModel->removePeaks( orig_roi_peaks );
27082665

27092666
std::vector<PeakDef> peaks_to_add;
27102667
for( auto p : new_roi_initial_peaks )
27112668
peaks_to_add.push_back( *p );
27122669

2713-
peakModel->addPeaks( peaks_to_add );
2670+
m_peakModel->addPeaks( peaks_to_add );
27142671
}
27152672
}else
27162673
{
@@ -2770,15 +2727,18 @@ void D3SpectrumDisplayDiv::performExistingRoiEdgeDragWork( double new_lower_ener
27702727

27712728
if( for_background || for_secondary )
27722729
{
2773-
final_mondified_peaks->insert( end(*final_mondified_peaks), begin(new_roi_initial_peaks), end(new_roi_initial_peaks) );
2774-
std::sort( begin(*final_mondified_peaks), end(*final_mondified_peaks), &PeakDef::lessThanByMeanShrdPtr );
2775-
2776-
InterSpec::instance()->setPeaks( spec_type, final_mondified_peaks ); // will take care of undo/redo
2730+
if( origpeaks )
2731+
{
2732+
final_mondified_peaks->insert( end(*final_mondified_peaks), begin(new_roi_initial_peaks), end(new_roi_initial_peaks) );
2733+
std::sort( begin(*final_mondified_peaks), end(*final_mondified_peaks), &PeakDef::lessThanByMeanShrdPtr );
2734+
2735+
m_peakModel->setPeaks( *final_mondified_peaks, spec_type ); // will take care of undo/redo
2736+
}
27772737
}else
27782738
{
2779-
assert( peakModel );
2780-
peakModel->removePeaks( orig_roi_peaks );
2781-
peakModel->addPeaks( peaks_to_add );
2739+
assert( m_peakModel );
2740+
m_peakModel->removePeaks( orig_roi_peaks );
2741+
m_peakModel->addPeaks( peaks_to_add );
27822742
}
27832743

27842744
m_continuum_being_drug.reset();
@@ -2797,11 +2757,11 @@ void D3SpectrumDisplayDiv::performExistingRoiEdgeDragWork( double new_lower_ener
27972757
{
27982758
if( for_background || for_secondary )
27992759
{
2800-
InterSpec::instance()->setPeaks( spec_type, final_mondified_peaks ); //will take care of undo/redo
2760+
m_peakModel->setPeaks( *final_mondified_peaks, spec_type );
28012761
}else
28022762
{
2803-
assert( peakModel );
2804-
peakModel->removePeaks( orig_roi_peaks );
2763+
assert( m_peakModel );
2764+
m_peakModel->removePeaks( orig_roi_peaks );
28052765
}
28062766
}
28072767
}//if( not narrow region ) / else
@@ -3070,7 +3030,7 @@ void D3SpectrumDisplayDiv::performDragCreateRoiWork( double lower_energy, double
30703030

30713031
UndoRedoManager::PeakModelChange peak_undo_creator;
30723032

3073-
deque< PeakModel::PeakShrdPtr > preaddpeaks, postaddpeaks;
3033+
deque<shared_ptr<const PeakDef>> preaddpeaks, postaddpeaks;
30743034
if( peakModel->peaks() ) //should always be true, but JIC
30753035
preaddpeaks = *peakModel->peaks();
30763036

@@ -3085,7 +3045,7 @@ void D3SpectrumDisplayDiv::performDragCreateRoiWork( double lower_energy, double
30853045
if( peakModel->peaks() ) //should always be true, but JIC
30863046
postaddpeaks = *peakModel->peaks();
30873047

3088-
vector< PeakModel::PeakShrdPtr > added_peaks;
3048+
vector<shared_ptr<const PeakDef>> added_peaks;
30893049
for( const auto &p : postaddpeaks )
30903050
{
30913051
if( !std::count(begin(preaddpeaks), end(preaddpeaks), p) )
@@ -3323,8 +3283,6 @@ D3SpectrumDisplayDiv::~D3SpectrumDisplayDiv()
33233283
// Cleanup the instance-specific style rules we created.
33243284
WCssStyleSheet &style = wApp->styleSheet();
33253285
for( const auto &name_rule : m_cssRules )
3326-
{
33273286
style.removeRule( name_rule.second );
3328-
}
33293287
m_cssRules.clear();
33303288
}//~D3SpectrumDisplayDiv()

src/DetectionLimitTool.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1318,7 +1318,7 @@ DetectionLimitTool::DetectionLimitTool( InterSpec *viewer,
13181318
m_our_meas = make_shared<SpecMeas>();
13191319
m_our_meas->setDetector( primaryMeas->detector() );
13201320
m_our_meas->add_measurement( ourspec, true );
1321-
m_peakModel->setPeakFromSpecMeas( m_our_meas, {ourspec->sample_number()} );
1321+
m_peakModel->setPeakFromSpecMeas( m_our_meas, {ourspec->sample_number()}, SpecUtils::SpectrumType::Foreground );
13221322
m_chart->setData( ourspec, false );
13231323
}//if( spec )
13241324

src/EnergyCalAddActions.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,12 @@ void ConvertCalTypeTool::convertLowerChannelEnegies( const size_t ncoeffs,
567567

568568
const auto foreground = viewer->measurment(SpecUtils::SpectrumType::Foreground);
569569
const auto &foreSamples = viewer->displayedSamples(SpecUtils::SpectrumType::Foreground);
570+
571+
const auto background = viewer->measurment(SpecUtils::SpectrumType::Background);
572+
const auto &backSamples = viewer->displayedSamples(SpecUtils::SpectrumType::Background);
573+
574+
const auto secondary = viewer->measurment(SpecUtils::SpectrumType::SecondForeground);
575+
const auto &secoSamples = viewer->displayedSamples(SpecUtils::SpectrumType::SecondForeground);
570576

571577
for( const auto &mp : updated_peaks )
572578
{
@@ -576,7 +582,11 @@ void ConvertCalTypeTool::convertLowerChannelEnegies( const size_t ncoeffs,
576582
spec->setPeaks( newpeaks, samples );
577583

578584
if( (spec == foreground) && (samples == foreSamples) )
579-
peakmodel->setPeakFromSpecMeas( spec, samples);
585+
peakmodel->setPeakFromSpecMeas( spec, samples, SpecUtils::SpectrumType::Foreground );
586+
else if( (spec == background) && (samples == backSamples) )
587+
peakmodel->setPeakFromSpecMeas( spec, samples, SpecUtils::SpectrumType::Background );
588+
else if( (spec == secondary) && (samples == secoSamples) )
589+
peakmodel->setPeakFromSpecMeas( spec, samples, SpecUtils::SpectrumType::SecondForeground );
580590
}//for( const auto &mp : updated_peaks )
581591

582592

0 commit comments

Comments
 (0)