Commit 4ac1949f authored by Alexander Stukowski's avatar Alexander Stukowski

Reestablished capability of Grain Segmentation modifier to output the RMSD...

Reestablished capability of Grain Segmentation modifier to output the RMSD histogram and the neighbor bond graph
parent 6bc3a07e
......@@ -20,24 +20,17 @@
///////////////////////////////////////////////////////////////////////////////
#include <plugins/crystalanalysis/CrystalAnalysis.h>
#include <plugins/crystalanalysis/modifier/grains/GrainSegmentationEngine.h>
#include <plugins/crystalanalysis/modifier/grains/GrainSegmentationModifier.h>
#include <plugins/particles/gui/modifier/analysis/StructureListParameterUI.h>
#include <gui/properties/FloatParameterUI.h>
#include <gui/properties/IntegerParameterUI.h>
#include <gui/properties/BooleanParameterUI.h>
#include <gui/properties/VariantComboBoxParameterUI.h>
#include <gui/properties/SubObjectParameterUI.h>
#include <gui/properties/BooleanGroupBoxParameterUI.h>
#include <gui/utilities/concurrent/ProgressDialog.h>
#include <core/dataset/DataSetContainer.h>
#include <plugins/crystalanalysis/modifier/grains/GrainSegmentationEngine.h>
#include <plugins/crystalanalysis/modifier/grains/GrainSegmentationModifier.h>
#include "GrainSegmentationModifierEditor.h"
#include <3rdparty/qwt/qwt_plot.h>
#include <3rdparty/qwt/qwt_plot_curve.h>
#include <3rdparty/qwt/qwt_plot_zoneitem.h>
#include <3rdparty/qwt/qwt_plot_grid.h>
namespace Ovito { namespace Plugins { namespace CrystalAnalysis {
......@@ -75,15 +68,25 @@ void GrainSegmentationModifierEditor::createUI(const RolloutInsertionParameters&
sublayout2->addWidget(minGrainAtomCountUI->label(), 2, 0);
sublayout2->addLayout(minGrainAtomCountUI->createFieldLayout(), 2, 1);
QGroupBox* debuggingParamsBox = new QGroupBox(tr("Debugging options"));
layout->addWidget(debuggingParamsBox);
sublayout2 = new QGridLayout(debuggingParamsBox);
sublayout2->setContentsMargins(4,4,4,4);
sublayout2->setSpacing(4);
sublayout2->setColumnStretch(1, 1);
// Orphan atom adoption
BooleanParameterUI* orphanAdoptionUI = new BooleanParameterUI(this, PROPERTY_FIELD(GrainSegmentationModifier::orphanAdoption));
sublayout2->addWidget(orphanAdoptionUI->checkBox(), 3, 0, 1, 2);
orphanAdoptionUI->checkBox()->setText(tr("Orphan atom adoption"));
sublayout2->addWidget(orphanAdoptionUI->checkBox(), 0, 0, 1, 2);
BooleanParameterUI* outputBondsUI = new BooleanParameterUI(this, PROPERTY_FIELD(GrainSegmentationModifier::outputBonds));
sublayout2->addWidget(outputBondsUI->checkBox(), 1, 0, 1, 2);
#if 0
QPushButton* grainTrackingButton = new QPushButton(tr("Perform grain tracking..."));
layout->addWidget(grainTrackingButton);
connect(grainTrackingButton, &QPushButton::clicked, this, &GrainSegmentationModifierEditor::onPerformGrainTracking);
#endif
// Status label.
layout->addWidget(statusLabel());
......@@ -94,15 +97,17 @@ void GrainSegmentationModifierEditor::createUI(const RolloutInsertionParameters&
layout->addWidget(new QLabel(tr("Structure types:")));
layout->addWidget(structureTypesPUI->tableWidget());
_plot = new QwtPlot();
_plot->setMinimumHeight(240);
_plot->setMaximumHeight(240);
_plot->setCanvasBackground(Qt::white);
_plot->setAxisTitle(QwtPlot::xBottom, tr("RMSD"));
_plot->setAxisTitle(QwtPlot::yLeft, tr("Count"));
// Create plot widget for RMSD distribution.
_rmsdPlotWidget = new DataSeriesPlotWidget();
_rmsdPlotWidget->setMinimumHeight(200);
_rmsdPlotWidget->setMaximumHeight(200);
_rmsdRangeIndicator = new QwtPlotZoneItem();
_rmsdRangeIndicator->setOrientation(Qt::Vertical);
_rmsdRangeIndicator->setZ(1);
_rmsdRangeIndicator->attach(_rmsdPlotWidget);
_rmsdRangeIndicator->hide();
layout->addSpacing(10);
layout->addWidget(_plot);
layout->addWidget(_rmsdPlotWidget);
connect(this, &GrainSegmentationModifierEditor::contentsReplaced, this, &GrainSegmentationModifierEditor::plotHistogram);
}
......@@ -111,7 +116,7 @@ void GrainSegmentationModifierEditor::createUI(const RolloutInsertionParameters&
******************************************************************************/
bool GrainSegmentationModifierEditor::referenceEvent(RefTarget* source, const ReferenceEvent& event)
{
if(event.sender() == editObject() && (event.type() == ReferenceEvent::ObjectStatusChanged || event.type() == ReferenceEvent::TargetChanged)) {
if(source == modifierApplication() && event.type() == ReferenceEvent::PipelineCacheUpdated) {
plotHistogramLater(this);
}
return ModifierPropertiesEditor::referenceEvent(source, event);
......@@ -122,52 +127,26 @@ bool GrainSegmentationModifierEditor::referenceEvent(RefTarget* source, const Re
******************************************************************************/
void GrainSegmentationModifierEditor::plotHistogram()
{
#if 0
//TODO: put this back in
GrainSegmentationModifier* modifier = static_object_cast<GrainSegmentationModifier>(editObject());
GrainSegmentationModifierApplication* modApp = dynamic_object_cast<GrainSegmentationModifierApplication>(someModifierApplication());
if(!modifier || !modApp || modApp->rmsdHistogramData().empty()) {
if(_plotCurve) _plotCurve->hide();
return;
}
QVector<QPointF> plotData(modApp->rmsdHistogramData().size());
double binSize = modApp->rmsdHistogramBinSize();
double maxHistogramData = 0;
for(int i = 0; i < modApp->rmsdHistogramData().size(); i++) {
plotData[i].rx() = binSize * ((double)i + 0.5);
plotData[i].ry() = modApp->rmsdHistogramData()[i];
maxHistogramData = std::max(maxHistogramData, plotData[i].y());
if(modifier && modifier->rmsdCutoff() > 0) {
_rmsdRangeIndicator->setInterval(0, modifier->rmsdCutoff());
_rmsdRangeIndicator->show();
}
if(!_plotCurve) {
_plotCurve = new QwtPlotCurve();
_plotCurve->setRenderHint(QwtPlotItem::RenderAntialiased, true);
_plotCurve->setBrush(QColor(255, 160, 100));
_plotCurve->attach(_plot);
QwtPlotGrid* plotGrid = new QwtPlotGrid();
plotGrid->setPen(Qt::gray, 0, Qt::DotLine);
plotGrid->attach(_plot);
else {
_rmsdRangeIndicator->hide();
}
_plotCurve->setSamples(plotData);
if(modifier->rmsdCutoff() > 0) {
if(!_rmsdRange) {
_rmsdRange = new QwtPlotZoneItem();
_rmsdRange->setOrientation(Qt::Vertical);
_rmsdRange->setZ(_plotCurve->z() + 1);
_rmsdRange->attach(_plot);
}
_rmsdRange->show();
_rmsdRange->setInterval(0, modifier->rmsdCutoff());
if(modifierApplication()) {
// Request the modifier's pipeline output.
const PipelineFlowState& state = getModifierOutput();
// Look up the data series in the modifier's pipeline output.
_rmsdPlotWidget->setSeries(state.getObjectBy<DataSeriesObject>(modifierApplication(), QStringLiteral("grains-rmsd")));
}
else if(_rmsdRange) {
_rmsdRange->hide();
else {
_rmsdPlotWidget->reset();
}
_plot->replot();
#endif
}
/******************************************************************************
......
......@@ -23,11 +23,10 @@
#include <plugins/crystalanalysis/CrystalAnalysis.h>
#include <plugins/stdobj/gui/widgets/DataSeriesPlotWidget.h>
#include <gui/properties/ModifierPropertiesEditor.h>
#include <core/utilities/DeferredMethodInvocation.h>
class QwtPlot;
class QwtPlotCurve;
class QwtPlotZoneItem;
namespace Ovito { namespace Plugins { namespace CrystalAnalysis {
......@@ -64,13 +63,10 @@ protected:
private:
/// The graph widget to display the RMSD histogram.
QwtPlot* _plot;
/// The plot item for the histogram.
QwtPlotCurve* _plotCurve = nullptr;
DataSeriesPlotWidget* _rmsdPlotWidget;
/// Marks the RMSD cutoff in the histogram plot.
QwtPlotZoneItem* _rmsdRange = nullptr;
QwtPlotZoneItem* _rmsdRangeIndicator;
/// For deferred invocation of the plot repaint function.
DeferredMethodInvocation<GrainSegmentationModifierEditor, &GrainSegmentationModifierEditor::plotHistogram> plotHistogramLater;
......
......@@ -24,11 +24,8 @@
#include <plugins/crystalanalysis/CrystalAnalysis.h>
#include <plugins/particles/modifier/analysis/StructureIdentificationModifier.h>
#include <plugins/particles/Particles.h>
#include <plugins/particles/objects/ParticlesObject.h>
#include <plugins/particles/objects/BondsObject.h>
#include <plugins/particles/modifier/analysis/ptm/PTMAlgorithm.h>
#include <boost/optional/optional.hpp>
......@@ -46,39 +43,36 @@ public:
ParticleOrderingFingerprint fingerprint, ConstPropertyPtr positions, const SimulationCell& simCell,
const QVector<bool>& typesToIdentify, ConstPropertyPtr selection,
FloatType rmsdCutoff, FloatType misorientationThreshold,
int minGrainAtomCount, bool orphanAdoption);
int minGrainAtomCount, bool orphanAdoption, bool outputBonds);
/// Performs the computation.
virtual void perform() override;
/// This method is called by the system to free memory and release any working data after the
/// This method is called by the system to free memory and release any working data after the
/// computation has been successfully completed.
virtual void cleanup() override {
_neighborLists.reset();
decltype(_distanceSortedAtoms){}.swap(_distanceSortedAtoms);
decltype(_clusterOrientations){}.swap(_clusterOrientations);
decltype(_clusterSizes){}.swap(_clusterSizes);
if(!_outputBonds) {
decltype(_latticeNeighborBonds){}.swap(_latticeNeighborBonds);
_neighborDisorientationAngles.reset();
}
StructureIdentificationEngine::cleanup();
}
/// Injects the computed results into the data pipeline.
virtual void emitResults(TimePoint time, ModifierApplication* modApp, PipelineFlowState& state) override;
/// Returns the per-atom RMSD values computed by the PTM algorithm.
const PropertyPtr& rmsd() const { return _rmsd; }
/// Returns the computed RMSD histogram data.
const QVector<int>& rmsdHistogramData() const { return _rmsdHistogramData; }
/// Returns the RMSD value range of the histogram.
FloatType rmsdHistogramRange() const { return _rmsdHistogramRange; }
/// Returns the bin size of the RMSD histogram.
FloatType rmsdHistogramBinSize() const { return _rmsdHistogramBinSize; }
/// Replaces the stored RMSD histogram data.
void setRmsdHistogram(QVector<int> counts, FloatType rmsdHistogramBinSize) {
_rmsdHistogramData = std::move(counts);
_rmsdHistogramBinSize = rmsdHistogramBinSize;
}
/// Returns the histogram of computed RMSD values.
const PropertyPtr& rmsdHistogram() const { return _rmsdHistogram; }
/// Returns the computed per-particle lattice orientations.
const PropertyPtr& orientations() const { return _orientations; }
......@@ -87,17 +81,7 @@ public:
const PropertyPtr& atomClusters() const { return _atomClusters; }
/// Returns the bonds generated between neighboring lattice atoms.
const PropertyPtr& latticeNeighborBonds() const { return _latticeNeighborBonds; }
/// Returns the PBC shift vectors of bonds.
const PropertyPtr& bondPBCShiftVectors() const { return _bondPBCShiftVectors; }
/// Allocates the bonds arrays.
void allocateBonds(size_t count) {
_latticeNeighborBonds = BondsObject::OOClass().createStandardStorage(count, BondsObject::TopologyProperty, false);
_bondPBCShiftVectors = BondsObject::OOClass().createStandardStorage(count, BondsObject::PeriodicImageProperty, true);
_neighborDisorientationAngles = std::make_shared<PropertyStorage>(count, PropertyStorage::Float, 1, 0, QStringLiteral("Disorientation"), false);
}
const std::vector<Bond>& latticeNeighborBonds() const { return _latticeNeighborBonds; }
/// Returns the computed disorientation angles between neighboring lattice atoms.
const PropertyPtr& neighborDisorientationAngles() const { return _neighborDisorientationAngles; }
......@@ -132,7 +116,7 @@ private:
/// Counts the number of superclusters
size_t _numSuperclusters = 0;
/// Stores the number of atoms in each supercluster.
std::vector<size_t> _superclusterSizes;
......@@ -142,10 +126,10 @@ private:
/// The merging criterion threshold.
FloatType _mergingThreshold;
/// The minimum number of crystalline atoms per grain.
/// The minimum number of crystalline atoms per grain.
int _minGrainAtomCount;
/// Whether to adopt orphan atoms
/// Whether to adopt orphan atoms.
int _orphanAdoption;
/// Stores the list of neighbors of each lattice atom.
......@@ -159,7 +143,7 @@ private:
/// Stores the average lattice orientation of each cluster.
std::vector<Quaternion> _clusterOrientations;
/// Stores the number of atoms in each cluster.
std::vector<qlonglong> _clusterSizes;
......@@ -167,10 +151,10 @@ private:
const PropertyPtr _rmsd;
/// Histogram of the RMSD values computed by the PTM algorithm.
QVector<int> _rmsdHistogramData;
PropertyPtr _rmsdHistogram;
/// Bin size of the RMSD histogram.
FloatType _rmsdHistogramBinSize;
/// The value range of the RMSD histogram.
FloatType _rmsdHistogramRange;
/// The computed per-particle lattice orientations.
PropertyPtr _orientations;
......@@ -178,11 +162,11 @@ private:
/// The particle to cluster assignment.
PropertyPtr _atomClusters;
/// The bonds generated between neighboring lattice atoms.
PropertyPtr _latticeNeighborBonds;
/// Flag controlling the output of generated bonds to the data pipeline.
bool _outputBonds;
/// The PBC shift vectors of bonds.
PropertyPtr _bondPBCShiftVectors;
/// The bonds generated between neighboring lattice atoms.
std::vector<Bond> _latticeNeighborBonds;
/// The computed disorientation angles between neighboring lattice atoms.
PropertyPtr _neighborDisorientationAngles;
......
......@@ -20,20 +20,17 @@
///////////////////////////////////////////////////////////////////////////////
#include <plugins/crystalanalysis/CrystalAnalysis.h>
#include <plugins/stdobj/simcell/SimulationCellObject.h>
#include <plugins/particles/objects/BondsVis.h>
#include <plugins/stdobj/simcell/SimulationCellObject.h>
#include <plugins/stdobj/properties/PropertyStorage.h>
#include <plugins/stdobj/series/DataSeriesObject.h>
#include <core/utilities/concurrent/Promise.h>
#include <core/utilities/concurrent/TaskManager.h>
#include <core/utilities/units/UnitsManager.h>
#include "GrainSegmentationModifier.h"
#include "GrainSegmentationEngine.h"
//#include "GrainTrackingEngine.h"
#include <plugins/particles/Particles.h>
#include <plugins/stdobj/properties/PropertyStorage.h>
#include <plugins/stdobj/series/DataSeriesObject.h>
#include <core/dataset/pipeline/ModifierApplication.h>
#include <core/dataset/DataSet.h>
#include "GrainSegmentationModifier.h"
#include "GrainSegmentationEngine.h"
#include <ptm/ptm_functions.h>
......@@ -45,20 +42,19 @@ DEFINE_PROPERTY_FIELD(GrainSegmentationModifier, mergingThreshold);
DEFINE_PROPERTY_FIELD(GrainSegmentationModifier, minGrainAtomCount);
DEFINE_PROPERTY_FIELD(GrainSegmentationModifier, orphanAdoption);
DEFINE_PROPERTY_FIELD(GrainSegmentationModifier, onlySelectedParticles);
DEFINE_PROPERTY_FIELD(GrainSegmentationModifier, outputBonds);
DEFINE_REFERENCE_FIELD(GrainSegmentationModifier, bondsVis);
SET_PROPERTY_FIELD_LABEL(GrainSegmentationModifier, rmsdCutoff, "RMSD cutoff");
SET_PROPERTY_FIELD_LABEL(GrainSegmentationModifier, mergingThreshold, "Merging threshold");
SET_PROPERTY_FIELD_LABEL(GrainSegmentationModifier, minGrainAtomCount, "Minimum grain size (# of atoms)");
SET_PROPERTY_FIELD_LABEL(GrainSegmentationModifier, orphanAdoption, "Adopt orphan atoms");
SET_PROPERTY_FIELD_LABEL(GrainSegmentationModifier, onlySelectedParticles, "Use only selected particles");
SET_PROPERTY_FIELD_LABEL(GrainSegmentationModifier, outputBonds, "Output bonds");
SET_PROPERTY_FIELD_LABEL(GrainSegmentationModifier, bondsVis, "Bonds display");
SET_PROPERTY_FIELD_UNITS_AND_MINIMUM(GrainSegmentationModifier, rmsdCutoff, FloatParameterUnit, 0);
SET_PROPERTY_FIELD_UNITS_AND_MINIMUM(GrainSegmentationModifier, minGrainAtomCount, IntegerParameterUnit, 1);
SET_PROPERTY_FIELD_UNITS_AND_MINIMUM(GrainSegmentationModifier, mergingThreshold, FloatParameterUnit, 0);
//IMPLEMENT_OVITO_CLASS(GrainSegmentationModifierApplication);
//SET_MODIFIER_APPLICATION_TYPE(GrainSegmentationModifier, GrainSegmentationModifierApplication);
/******************************************************************************
* Constructs the modifier object.
******************************************************************************/
......@@ -66,7 +62,9 @@ GrainSegmentationModifier::GrainSegmentationModifier(DataSet* dataset) : Structu
_rmsdCutoff(0.1),
_minGrainAtomCount(100),
_onlySelectedParticles(false),
_mergingThreshold(0.1)
_mergingThreshold(0.1),
_orphanAdoption(true),
_outputBonds(false)
{
// Define the structure types.
createStructureType(PTMAlgorithm::OTHER, ParticleType::PredefinedStructureType::OTHER);
......@@ -79,9 +77,8 @@ GrainSegmentationModifier::GrainSegmentationModifier(DataSet* dataset) : Structu
createStructureType(PTMAlgorithm::HEX_DIAMOND, ParticleType::PredefinedStructureType::HEX_DIAMOND)->setEnabled(false);
createStructureType(PTMAlgorithm::GRAPHENE, ParticleType::PredefinedStructureType::GRAPHENE)->setEnabled(false);
// Create the visual element for the bonds (display is disabled by default).
// Create the visual element for the bonds.
setBondsVis(new BondsVis(dataset));
bondsVis()->setEnabled(false);
}
/******************************************************************************
......@@ -110,7 +107,7 @@ std::shared_ptr<GrainSegmentationEngine> GrainSegmentationModifier::createSegmen
// Create engine object. Pass all relevant modifier parameters to the engine as well as the input data.
return std::make_shared<GrainSegmentationEngine>(particles, posProperty->storage(), simCell->data(),
getTypesToIdentify(PTMAlgorithm::NUM_STRUCTURE_TYPES), std::move(selectionProperty),
rmsdCutoff(), mergingThreshold(), minGrainAtomCount(), orphanAdoption());
rmsdCutoff(), mergingThreshold(), minGrainAtomCount(), orphanAdoption(), outputBonds());
}
/******************************************************************************
......@@ -140,31 +137,16 @@ void GrainSegmentationEngine::emitResults(TimePoint time, ModifierApplication* m
if(atomClusters())
particles->createProperty(atomClusters());
#if 0
//TODO: put this back in
// Output lattice neighbor bonds.
if(latticeNeighborBonds()) {
for(int i = output.objects().size()-1; i>=0; i--)
if(dynamic_object_cast<BondProperty>(output.objects()[i]))
output.removeObjectByIndex(i);
OORef<BondProperty> topologyPropertyObj = BondProperty::createFromStorage(modifier->dataset(), latticeNeighborBonds());
topologyPropertyObj->setVisElement(modifier->bondsVis());
output.addObject(topologyPropertyObj);
poh.setOutputBondCount(latticeNeighborBonds()->size());
poh.outputProperty<BondProperty>(bondPBCShiftVectors());
poh.outputProperty<BondProperty>(neighborDisorientationAngles());
// Output the edges of the neighbor graph.
if(_outputBonds && modifier->outputBonds()) {
particles->addBonds(latticeNeighborBonds(), modifier->bondsVis(), { neighborDisorientationAngles() });
}
#endif
// Store the RMSD histogram in the ModifierApplication.
//static_object_cast<GrainSegmentationModifierApplication>(modApp)->setRmsdHistogram(rmsdHistogramData(), rmsdHistogramBinSize());
//TODO: put this back in
//DataSeriesObject* seriesObj = state.createObject<DataSeriesObject>(QStringLiteral("grains-rmsd"), modApp, DataSeriesObject::Line, GrainSegmentationModifier::tr("RMSD distribution"), rmsdHistogram());
//seriesObj->setAxisLabelX(GrainSegmentationModifier::tr("RMSD"));
//seriesObj->setIntervalStart(0);
//seriesObj->setIntervalEnd(rmsdHistogramRange());
// Output RMSD histogram.
DataSeriesObject* seriesObj = state.createObject<DataSeriesObject>(QStringLiteral("grains-rmsd"), modApp, DataSeriesObject::Line, GrainSegmentationModifier::tr("RMSD distribution"), rmsdHistogram());
seriesObj->setAxisLabelX(GrainSegmentationModifier::tr("RMSD"));
seriesObj->setIntervalStart(0);
seriesObj->setIntervalEnd(rmsdHistogramRange());
size_t numGrains = atomClusters()->size() == 0 ? 0 : (*std::max_element(atomClusters()->constDataInt64(), atomClusters()->constDataInt64() + atomClusters()->size()));
state.setStatus(PipelineStatus(PipelineStatus::Success, GrainSegmentationModifier::tr("Found %1 grains").arg(numGrains)));
......@@ -218,7 +200,7 @@ bool GrainSegmentationModifier::trackGrains(TaskManager& taskManager, ModifierAp
// Update progress display.
task.setProgressValue(task.progressValue() + 1);
if(task.isCanceled())
if(task.isCanceled())
return false;
}
......@@ -232,7 +214,7 @@ bool GrainSegmentationModifier::trackGrains(TaskManager& taskManager, ModifierAp
// Release working data structures that are no longer needed.
grainTrackingEngine->cleanup();
return true;
}
#endif
......
......@@ -25,8 +25,6 @@
#include <plugins/crystalanalysis/CrystalAnalysis.h>
#include <plugins/particles/modifier/analysis/StructureIdentificationModifier.h>
#include <plugins/particles/objects/BondsVis.h>
#include <plugins/particles/Particles.h>
#include <plugins/particles/objects/ParticlesObject.h>
#include <plugins/stdobj/series/DataSeriesObject.h>
......@@ -78,45 +76,11 @@ private:
/// Controls whether only selected particles should be taken into account.
DECLARE_MODIFIABLE_PROPERTY_FIELD(bool, onlySelectedParticles, setOnlySelectedParticles);
/// The display object for rendering the bonds created by the modifier.
/// The visual element for rendering the bonds created by the modifier.
DECLARE_MODIFIABLE_REFERENCE_FIELD_FLAGS(BondsVis, bondsVis, setBondsVis, PROPERTY_FIELD_DONT_PROPAGATE_MESSAGES | PROPERTY_FIELD_MEMORIZE);
//};
/**
* \brief The type of ModifierApplication created for a GrainSegmentationModifier
* when it is inserted into in a data pipeline. It stores the last computation results
* so that they can be displayed in the modifier's user interface.
*/
//class OVITO_PARTICLES_EXPORT GrainSegmentationModifierApplication : public StructureIdentificationModifierApplication
//{
// Q_OBJECT
// OVITO_CLASS(GrainSegmentationModifierApplication)
public:
/// Constructor.
//Q_INVOKABLE GrainSegmentationModifierApplication(DataSet* dataset) : StructureIdentificationModifierApplication(dataset) {}
/// Returns the histogram of computed RMSD values.
const QVector<int>& rmsdHistogramData() const { return _rmsdHistogramData; }
/// Returns the bin size of the RMSD histogram.
FloatType rmsdHistogramBinSize() const { return _rmsdHistogramBinSize; }
/// Replaces the stored histogram data.
void setRmsdHistogram(QVector<int> counts, FloatType rmsdHistogramBinSize) {
_rmsdHistogramData = std::move(counts);
_rmsdHistogramBinSize = rmsdHistogramBinSize;
notifyDependents(ReferenceEvent::ObjectStatusChanged);
}
private:
/// The histogram of computed RMSD values.
QVector<int> _rmsdHistogramData;
/// The bin size of the RMSD histogram;
FloatType _rmsdHistogramBinSize = 0;
/// Controls the output of bonds by the modifier.
DECLARE_MODIFIABLE_PROPERTY_FIELD(bool, outputBonds, setOutputBonds);
};
} // End of namespace
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment