MDANSE-GUI 2.0.0__tar.gz → 2.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mdanse_gui-2.0.0/Src/MDANSE_GUI.egg-info → mdanse_gui-2.0.1}/PKG-INFO +1 -14
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/README.md +0 -13
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/ElementsDatabaseEditor.py +4 -4
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/QVectorsWidget.py +19 -16
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Resources/InstrumentDefinitions.toml +6 -0
- mdanse_gui-2.0.1/Src/MDANSE_GUI/Resources/splash.png +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Models/JobHolder.py +2 -2
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Plotters/Heatmap.py +0 -2
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Plotters/Text.py +0 -5
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Plotters/Vectors.py +2 -2
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Views/ActionsTree.py +1 -1
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Views/PlotDataView.py +20 -8
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Visualisers/Action.py +2 -2
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Visualisers/DataPlotter.py +1 -1
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Visualisers/InstrumentInfo.py +5 -0
- mdanse_gui-2.0.1/Src/MDANSE_GUI/Widgets/GeneralWidgets.py +254 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1/Src/MDANSE_GUI.egg-info}/PKG-INFO +1 -14
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/pyproject.toml +1 -1
- mdanse_gui-2.0.0/Src/MDANSE_GUI/Resources/splash.png +0 -0
- mdanse_gui-2.0.0/Src/MDANSE_GUI/Widgets/GeneralWidgets.py +0 -710
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/AUTHORS +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/LICENSE +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Icons/MDANSE.ico +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Icons/MDANSE.png +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Icons/__init__.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Icons/blue_sphere.stl +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Icons/center_sphere.stl +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Icons/element.png +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Icons/periodic_table.png +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Icons/red_sphere.stl +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Icons/units.png +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Icons/user_definitions.png +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Icons/yellow_sphere.stl +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/AseInputFileWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/AtomMappingWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/AtomSelectionWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/AtomTransmutationWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/BackupWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/BooleanWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/CheckableComboBox.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/ComboWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/CorrelationFramesWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/DerivativeOrderWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/DistHistCutoffWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/FloatWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/FramesWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/HDFTrajectoryWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/InputFileWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/InstrumentResolutionWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/IntegerWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/InterpolationOrderWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/MDAnalysisCoordinateFileWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/MDAnalysisMDTrajTimeStepWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/MDAnalysisTopologyFileWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/MDTrajTopologyFileWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/MoleculeAndAxisWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/MoleculePreviewWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/MoleculeWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/MultiInputFileWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/MultipleCombosWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/OptionalFloatWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/OutputFilesWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/OutputStructureWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/OutputTrajectoryWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/PartialChargeWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/ProjectionWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/RangeWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/RunningModeWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/TrajectoryFilterWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/UnitCellWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/VectorWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/WeightsWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/WidgetBase.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/InputWidgets/__init__.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/MolecularViewer/AtomProperties.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/MolecularViewer/Controls.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/MolecularViewer/MolecularViewer.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/MolecularViewer/MolecularViewerExtended.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/MolecularViewer/MolecularViewerWithPicking.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/MolecularViewer/PropertyWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/MolecularViewer/TraceWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/MolecularViewer/__init__.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/MolecularViewer/readers/__init__.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/MolecularViewer/readers/hdf5wrapper.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/MolecularViewer/readers/i_reader.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/PeriodicTableViewer.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/PlotUtils.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Resources.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Scripts/__init__.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Scripts/mdanse_elements_database.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Scripts/mdanse_gui.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Scripts/mdanse_periodic_table.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Scripts/mdanse_units_editor.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Session/Logger.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Session/RecentFiles.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Session/Session.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Session/Settings.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Session/__init__.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Subprocess/JobStatusProcess.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Subprocess/Subprocess.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Subprocess/__init__.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/TabbedWindow.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/ConverterTab.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/GeneralTab.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/InstrumentTab.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/JobTab.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Layouts/DoublePanel.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Layouts/MultiPanel.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Layouts/SinglePanel.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Layouts/__init__.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/LoggingTab.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Models/GeneralModel.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Models/JobTree.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Models/PlotDataModel.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Models/PlottingContext.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Models/TrajectoryModel.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Models/__init__.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/PlotSelectionTab.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/PlotTab.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Plotters/Grid.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Plotters/Plotter.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Plotters/Single.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Plotters/Vectors3D.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Plotters/__init__.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/RunTab.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/TrajectoryTab.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Views/Delegates.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Views/InstrumentList.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Views/PlotDetailsView.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Views/RunTable.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Views/TrajectoryView.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Views/__init__.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Visualisers/DataWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Visualisers/InstrumentDetails.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Visualisers/JobLogInfo.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Visualisers/PlotHolder.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Visualisers/PlotSettings.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Visualisers/PlotWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Visualisers/TextInfo.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Visualisers/TrajectoryInfo.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Visualisers/View3D.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/Visualisers/__init__.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Tabs/__init__.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/UnitsEditor.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/UserSettingsEditor.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Utils.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Widgets/DefaultCombobox.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Widgets/DelayedButton.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Widgets/NormalisationWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Widgets/NotificationTabWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Widgets/PlotSettingsDialog.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Widgets/ResolutionDialog.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Widgets/ResolutionWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Widgets/RestrictedSlider.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Widgets/SelectionWidgets.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Widgets/StepValidator.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Widgets/StyleDialog.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Widgets/VectorWidget.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/Widgets/__init__.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/__init__.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI/main.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI.egg-info/SOURCES.txt +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI.egg-info/dependency_links.txt +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI.egg-info/entry_points.txt +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI.egg-info/requires.txt +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Src/MDANSE_GUI.egg-info/top_level.txt +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Tests/UnitTests/test_GeneralModel.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Tests/UnitTests/test_JobState.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Tests/UnitTests/test_PlottingContext.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Tests/UnitTests/test_SettingsFile.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/Tests/UnitTests/test_hdf5wrapper.py +0 -0
- {mdanse_gui-2.0.0 → mdanse_gui-2.0.1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: MDANSE_GUI
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.1
|
|
4
4
|
Summary: MDANSE GUI package - the graphical interface for MDANSE
|
|
5
5
|
Maintainer-email: Maciej Bartkowiak <maciej.bartkowiak@stfc.ac.uk>, "Chi Y. Cheng" <chi.cheng@stfc.ac.uk>, Jacob Wilkins <jacob.wilkins@stfc.ac.uk>
|
|
6
6
|
License: GNU GENERAL PUBLIC LICENSE
|
|
@@ -724,19 +724,6 @@ Molecular Dynamics Analysis for Neutron Scattering Experiments (MDANSE) software
|
|
|
724
724
|
|
|
725
725
|
The GUI depends on the [MDANSE package](https://pypi.org/project/MDANSE).
|
|
726
726
|
|
|
727
|
-
## Version information
|
|
728
|
-
|
|
729
|
-
This is the first release of MDANSE_GUI 2.0.0.
|
|
730
|
-
|
|
731
|
-
> [!NOTE]
|
|
732
|
-
> Considering the large number of different MD engines and analysis types,
|
|
733
|
-
> it is still possible that some conversion or analysis runs will not
|
|
734
|
-
> produce the expected results. Please report any problems
|
|
735
|
-
> you experience while using MDANSE by adding them to the
|
|
736
|
-
> [GitHub issue tracker](https://github.com/ISISNeutronMuon/MDANSE/issues).
|
|
737
|
-
> You can also send a message to MDANSE-help@stfc.ac.uk to get in touch
|
|
738
|
-
> with MDANSE developers.
|
|
739
|
-
|
|
740
727
|
## Quick start: installation
|
|
741
728
|
|
|
742
729
|
We recommend that you install MDANSE in a Python virtual environment.
|
|
@@ -7,19 +7,6 @@ Molecular Dynamics Analysis for Neutron Scattering Experiments (MDANSE) software
|
|
|
7
7
|
|
|
8
8
|
The GUI depends on the [MDANSE package](https://pypi.org/project/MDANSE).
|
|
9
9
|
|
|
10
|
-
## Version information
|
|
11
|
-
|
|
12
|
-
This is the first release of MDANSE_GUI 2.0.0.
|
|
13
|
-
|
|
14
|
-
> [!NOTE]
|
|
15
|
-
> Considering the large number of different MD engines and analysis types,
|
|
16
|
-
> it is still possible that some conversion or analysis runs will not
|
|
17
|
-
> produce the expected results. Please report any problems
|
|
18
|
-
> you experience while using MDANSE by adding them to the
|
|
19
|
-
> [GitHub issue tracker](https://github.com/ISISNeutronMuon/MDANSE/issues).
|
|
20
|
-
> You can also send a message to MDANSE-help@stfc.ac.uk to get in touch
|
|
21
|
-
> with MDANSE developers.
|
|
22
|
-
|
|
23
10
|
## Quick start: installation
|
|
24
11
|
|
|
25
12
|
We recommend that you install MDANSE in a Python virtual environment.
|
|
@@ -410,8 +410,8 @@ class ElementModel(QStandardItemModel):
|
|
|
410
410
|
column = idx.column()
|
|
411
411
|
row_name = self.verticalHeaderItem(row).text()
|
|
412
412
|
column_name = self.horizontalHeaderItem(column).text()
|
|
413
|
-
LOG.
|
|
414
|
-
LOG.
|
|
413
|
+
LOG.debug(f"data:{data}, text:{text}, row:{row}, column:{column}")
|
|
414
|
+
LOG.debug(f"column name={column_name}, row name={row_name}")
|
|
415
415
|
self.database.set_value(row_name, column_name, text)
|
|
416
416
|
self.save_changes()
|
|
417
417
|
|
|
@@ -610,7 +610,7 @@ class ElementModel(QStandardItemModel):
|
|
|
610
610
|
if new_label not in self.database.default_atoms_types:
|
|
611
611
|
item.setForeground(self.custom_header_brush)
|
|
612
612
|
self.setVerticalHeaderItem(self.rowCount() - 1, item)
|
|
613
|
-
LOG.
|
|
613
|
+
LOG.debug(f"self.all_row_names has length: {len(self.all_row_names)}")
|
|
614
614
|
|
|
615
615
|
@Slot()
|
|
616
616
|
def copy_rows(self):
|
|
@@ -708,7 +708,7 @@ class ElementModel(QStandardItemModel):
|
|
|
708
708
|
item.setForeground(self.custom_header_brush)
|
|
709
709
|
self.setHorizontalHeaderItem(self.columnCount() - 1, item)
|
|
710
710
|
self.parent().set_column_delegate(self.columnCount() - 1)
|
|
711
|
-
LOG.
|
|
711
|
+
LOG.debug(f"self.all_column_names has length: {len(self.all_column_names)}")
|
|
712
712
|
|
|
713
713
|
@Slot(dict)
|
|
714
714
|
def add_new_column(self, input_variables: dict):
|
|
@@ -141,22 +141,25 @@ class VectorModel(QStandardItemModel):
|
|
|
141
141
|
"""Validate input types and return a dictionary of input parameters."""
|
|
142
142
|
params = {}
|
|
143
143
|
all_inputs_are_valid = True
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
144
|
+
with block_signals(self):
|
|
145
|
+
# block signals to stop updateValue call on the colour
|
|
146
|
+
# background change
|
|
147
|
+
for rownum in range(self.rowCount()):
|
|
148
|
+
name = str(self.item(rownum, 0).text())
|
|
149
|
+
value = str(self.item(rownum, 1).text())
|
|
150
|
+
vtype = str(self.item(rownum, 2).text())
|
|
151
|
+
try:
|
|
152
|
+
params[name] = self.parse_vtype(vtype, value, name)
|
|
153
|
+
except ValueError:
|
|
154
|
+
params[name] = "failed"
|
|
155
|
+
if params[name] == "failed":
|
|
156
|
+
self.item(rownum, 1).setData(
|
|
157
|
+
QBrush(Qt.GlobalColor.red),
|
|
158
|
+
role=Qt.ItemDataRole.BackgroundRole,
|
|
159
|
+
)
|
|
160
|
+
all_inputs_are_valid = False
|
|
161
|
+
else:
|
|
162
|
+
self.item(rownum, 1).setData(0, role=Qt.ItemDataRole.BackgroundRole)
|
|
160
163
|
self.input_is_valid.emit(all_inputs_are_valid)
|
|
161
164
|
return params
|
|
162
165
|
|
|
@@ -11,6 +11,7 @@ _q_min = "0.1"
|
|
|
11
11
|
_q_max = "4.0"
|
|
12
12
|
_q_step = "0.1"
|
|
13
13
|
_q_width = "0.1"
|
|
14
|
+
_number_of_samples = "100000"
|
|
14
15
|
_vectors_per_shell = "1000"
|
|
15
16
|
_axis_1 = "1.0,0.0,0.0"
|
|
16
17
|
_axis_2 = "0.0,1.0,0.0"
|
|
@@ -28,6 +29,7 @@ _q_min = "0.18"
|
|
|
28
29
|
_q_max = "1.8"
|
|
29
30
|
_q_step = "0.05"
|
|
30
31
|
_q_width = "0.02"
|
|
32
|
+
_number_of_samples = "100000"
|
|
31
33
|
_vectors_per_shell = "1200"
|
|
32
34
|
_axis_1 = "1.0,0.0,0.0"
|
|
33
35
|
_axis_2 = "0.0,1.0,0.0"
|
|
@@ -45,6 +47,7 @@ _q_min = "0.37"
|
|
|
45
47
|
_q_max = "3.6"
|
|
46
48
|
_q_step = "0.05"
|
|
47
49
|
_q_width = "0.02"
|
|
50
|
+
_number_of_samples = "100000"
|
|
48
51
|
_vectors_per_shell = "1200"
|
|
49
52
|
_axis_1 = "1.0,0.0,0.0"
|
|
50
53
|
_axis_2 = "0.0,1.0,0.0"
|
|
@@ -62,6 +65,7 @@ _q_min = "0.18"
|
|
|
62
65
|
_q_max = "1.8"
|
|
63
66
|
_q_step = "0.05"
|
|
64
67
|
_q_width = "0.02"
|
|
68
|
+
_number_of_samples = "100000"
|
|
65
69
|
_vectors_per_shell = "1200"
|
|
66
70
|
_axis_1 = "1.0,0.0,0.0"
|
|
67
71
|
_axis_2 = "0.0,1.0,0.0"
|
|
@@ -79,6 +83,7 @@ _q_min = "0.37"
|
|
|
79
83
|
_q_max = "3.6"
|
|
80
84
|
_q_step = "0.05"
|
|
81
85
|
_q_width = "0.02"
|
|
86
|
+
_number_of_samples = "100000"
|
|
82
87
|
_vectors_per_shell = "1200"
|
|
83
88
|
_axis_1 = "1.0,0.0,0.0"
|
|
84
89
|
_axis_2 = "0.0,1.0,0.0"
|
|
@@ -96,6 +101,7 @@ _q_min = "0.1"
|
|
|
96
101
|
_q_max = "10.0"
|
|
97
102
|
_q_step = "0.1"
|
|
98
103
|
_q_width = "0.01"
|
|
104
|
+
_number_of_samples = "100000"
|
|
99
105
|
_vectors_per_shell = "1500"
|
|
100
106
|
_axis_1 = "1.0,0.0,0.0"
|
|
101
107
|
_axis_2 = "0.0,1.0,0.0"
|
|
Binary file
|
|
@@ -379,7 +379,7 @@ class JobHolder(QStandardItemModel):
|
|
|
379
379
|
communicator.finished.connect(item_th.on_finished) # bool
|
|
380
380
|
communicator.oscillate.connect(item_th.on_oscillate) # nothing
|
|
381
381
|
|
|
382
|
-
LOG.
|
|
382
|
+
LOG.debug("Watcher thread ready to start!")
|
|
383
383
|
watcher_thread.start()
|
|
384
384
|
try:
|
|
385
385
|
task_name = str(job_name)
|
|
@@ -407,7 +407,7 @@ class JobHolder(QStandardItemModel):
|
|
|
407
407
|
listener=listener,
|
|
408
408
|
)
|
|
409
409
|
|
|
410
|
-
LOG.
|
|
410
|
+
LOG.debug("Subprocess ready to start!")
|
|
411
411
|
subprocess_ref.start()
|
|
412
412
|
|
|
413
413
|
def startProcessAndLoad(self, job_vars: list):
|
|
@@ -428,12 +428,10 @@ class Text(Plotter):
|
|
|
428
428
|
optionally, new QTextBrowser to be used
|
|
429
429
|
|
|
430
430
|
"""
|
|
431
|
-
LOG.debug("Text.clear stared")
|
|
432
431
|
target = self._figure if figure is None else figure
|
|
433
432
|
if target is None:
|
|
434
433
|
return
|
|
435
434
|
target.clear()
|
|
436
|
-
LOG.debug("Text.clear finished")
|
|
437
435
|
|
|
438
436
|
def adjust_formatter(
|
|
439
437
|
self,
|
|
@@ -475,13 +473,11 @@ class Text(Plotter):
|
|
|
475
473
|
for displaying text.
|
|
476
474
|
|
|
477
475
|
"""
|
|
478
|
-
LOG.debug("Text.get_figure stared")
|
|
479
476
|
target = self._figure if figure is None else figure
|
|
480
477
|
if target is None:
|
|
481
478
|
LOG.error(f"PlottingContext can't plot to {target}")
|
|
482
479
|
return None
|
|
483
480
|
target.clear()
|
|
484
|
-
LOG.debug("Text.get_figure finished")
|
|
485
481
|
return target
|
|
486
482
|
|
|
487
483
|
def apply_settings(self, plotting_context: PlottingContext, colours=None):
|
|
@@ -526,7 +522,6 @@ class Text(Plotter):
|
|
|
526
522
|
ignored
|
|
527
523
|
|
|
528
524
|
"""
|
|
529
|
-
LOG.debug("Text.plot stared")
|
|
530
525
|
target = self.get_figure(figure)
|
|
531
526
|
if target is None:
|
|
532
527
|
return
|
|
@@ -121,8 +121,8 @@ class Vectors(Plotter):
|
|
|
121
121
|
target.canvas.draw()
|
|
122
122
|
single_plot_stack = [222, 221]
|
|
123
123
|
label_stack = [
|
|
124
|
-
"
|
|
125
|
-
"
|
|
124
|
+
"Used",
|
|
125
|
+
"Found",
|
|
126
126
|
]
|
|
127
127
|
for databundle in plotting_context.datasets().values():
|
|
128
128
|
dataset = databundle.dataset
|
|
@@ -41,6 +41,8 @@ MAX_BINS_PER_SHELL = 20
|
|
|
41
41
|
MIN_BINS_PER_SHELL = 1
|
|
42
42
|
MAX_BINS_PER_PLOT = 180
|
|
43
43
|
|
|
44
|
+
WEIGHTS_MULTIPLIER = 100
|
|
45
|
+
|
|
44
46
|
|
|
45
47
|
def qvector_binning_from_dict(
|
|
46
48
|
qvector_params: dict[str, Any],
|
|
@@ -384,9 +386,13 @@ def vector_q_statistics_datasets(
|
|
|
384
386
|
for shell_index in valid_shells
|
|
385
387
|
):
|
|
386
388
|
vec_weights = [dat[:] for dat in q_data("weights")]
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
389
|
+
if "n_q_vectors" in parent_dset and "n_q_found" in parent_dset:
|
|
390
|
+
used = np.array(parent_dset["n_q_vectors"])
|
|
391
|
+
found = np.array(parent_dset["n_q_found"])
|
|
392
|
+
else:
|
|
393
|
+
used = np.array([len(dat) for dat in q_data("weights")])
|
|
394
|
+
found = np.array([sum(dat[:]) for dat in q_data("weights")])
|
|
395
|
+
available_vectors = np.vstack((found, used)).T
|
|
390
396
|
else:
|
|
391
397
|
vec_weights = [np.ones_like(modq_shell) for modq_shell in modq_per_shell]
|
|
392
398
|
elif isinstance(source, QVectorsConfigurator):
|
|
@@ -407,10 +413,12 @@ def vector_q_statistics_datasets(
|
|
|
407
413
|
available_vectors = np.array(
|
|
408
414
|
[
|
|
409
415
|
(
|
|
410
|
-
|
|
411
|
-
|
|
416
|
+
n_found,
|
|
417
|
+
n_used,
|
|
418
|
+
)
|
|
419
|
+
for n_found, n_used in zip(
|
|
420
|
+
q_data("n_q_found"), q_data("n_q_vectors"), strict=False
|
|
412
421
|
)
|
|
413
|
-
for dat in q_data("weights")
|
|
414
422
|
],
|
|
415
423
|
)
|
|
416
424
|
vec_weights = [dat[:] for dat in q_data("weights")]
|
|
@@ -434,7 +442,11 @@ def vector_q_statistics_datasets(
|
|
|
434
442
|
linestyle=":",
|
|
435
443
|
marker="o",
|
|
436
444
|
data=available_vectors,
|
|
437
|
-
plot_axes={
|
|
445
|
+
plot_axes={
|
|
446
|
+
"|q|": qvals
|
|
447
|
+
if len(qvals) == len(available_vectors)
|
|
448
|
+
else qvals[valid_shells]
|
|
449
|
+
},
|
|
438
450
|
axes_units={"|q|": "1/nm"},
|
|
439
451
|
optional_filename=filename,
|
|
440
452
|
)
|
|
@@ -446,7 +458,7 @@ def vector_q_statistics_datasets(
|
|
|
446
458
|
data=[
|
|
447
459
|
np.concatenate(
|
|
448
460
|
[
|
|
449
|
-
int(vec_weights[shellindex][vecindex])
|
|
461
|
+
int(vec_weights[shellindex][vecindex] * WEIGHTS_MULTIPLIER)
|
|
450
462
|
* list(always_iterable(veclen))
|
|
451
463
|
for vecindex, veclen in enumerate(
|
|
452
464
|
modq_per_shell[shellindex] - qvals[shell],
|
|
@@ -271,7 +271,7 @@ class Action(QWidget):
|
|
|
271
271
|
self._widgets_in_layout[key] = widget
|
|
272
272
|
self._widgets.append(input_widget)
|
|
273
273
|
self._trajectory_configurator = input_widget._configurator
|
|
274
|
-
LOG.
|
|
274
|
+
LOG.debug("Set up input trajectory")
|
|
275
275
|
for key, value in settings.items():
|
|
276
276
|
if key in self._widgets_in_layout:
|
|
277
277
|
continue
|
|
@@ -310,7 +310,7 @@ class Action(QWidget):
|
|
|
310
310
|
)
|
|
311
311
|
if self._use_preview and has_preview:
|
|
312
312
|
input_widget.value_changed.connect(self.show_output_prediction)
|
|
313
|
-
LOG.
|
|
313
|
+
LOG.debug(f"Set up the right widget for {key}")
|
|
314
314
|
# self.handlers[key] = data_handler
|
|
315
315
|
self._has_been_initialised = True
|
|
316
316
|
self.check_inputs()
|
|
@@ -87,6 +87,7 @@ class SimpleInstrument:
|
|
|
87
87
|
self._q_width = 1.0
|
|
88
88
|
self._axis_1 = [1, 0, 0]
|
|
89
89
|
self._axis_2 = [0, 1, 0]
|
|
90
|
+
self._number_of_samples = 100000
|
|
90
91
|
self._vectors_per_shell = 100
|
|
91
92
|
self._force_equal_weights = False
|
|
92
93
|
self._configured = False
|
|
@@ -107,6 +108,7 @@ class SimpleInstrument:
|
|
|
107
108
|
["_q_max", "QLineEdit", "float"],
|
|
108
109
|
["_q_step", "QLineEdit", "float"],
|
|
109
110
|
["_q_width", "QLineEdit", "float"],
|
|
111
|
+
["_number_of_samples", "QLineEdit", "int"],
|
|
110
112
|
["_vectors_per_shell", "QLineEdit", "int"],
|
|
111
113
|
["_force_equal_weights", "QCheckBox", "bool"],
|
|
112
114
|
["_axis_1", "VectorWidget", "float"],
|
|
@@ -181,6 +183,9 @@ class SimpleInstrument:
|
|
|
181
183
|
if "width" in qvec_generator._configuration:
|
|
182
184
|
width = round(conversion_factor * float(_q_width), 6)
|
|
183
185
|
param_dictionary["width"] = width
|
|
186
|
+
if "n_samples" in qvec_generator._configuration:
|
|
187
|
+
num_samples = int(self._number_of_samples)
|
|
188
|
+
param_dictionary["n_samples"] = num_samples
|
|
184
189
|
if "n_vectors" in qvec_generator._configuration:
|
|
185
190
|
num_vectors = int(self._vectors_per_shell)
|
|
186
191
|
param_dictionary["n_vectors"] = num_vectors
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
# This file is part of MDANSE_GUI.
|
|
2
|
+
#
|
|
3
|
+
# MDANSE_GUI is free software: you can redistribute it and/or modify
|
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
6
|
+
# (at your option) any later version.
|
|
7
|
+
#
|
|
8
|
+
# This program is distributed in the hope that it will be useful,
|
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
11
|
+
# GNU General Public License for more details.
|
|
12
|
+
#
|
|
13
|
+
# You should have received a copy of the GNU General Public License
|
|
14
|
+
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
15
|
+
#
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import copy
|
|
19
|
+
from collections.abc import Iterable
|
|
20
|
+
from pathlib import PurePath
|
|
21
|
+
from typing import Union
|
|
22
|
+
|
|
23
|
+
from qtpy.QtCore import QObject, Qt, Signal, Slot
|
|
24
|
+
from qtpy.QtGui import (
|
|
25
|
+
QDoubleValidator,
|
|
26
|
+
QIntValidator,
|
|
27
|
+
QPalette,
|
|
28
|
+
QValidator,
|
|
29
|
+
)
|
|
30
|
+
from qtpy.QtWidgets import (
|
|
31
|
+
QCheckBox,
|
|
32
|
+
QComboBox,
|
|
33
|
+
QDialog,
|
|
34
|
+
QFileDialog,
|
|
35
|
+
QFormLayout,
|
|
36
|
+
QHBoxLayout,
|
|
37
|
+
QLabel,
|
|
38
|
+
QLineEdit,
|
|
39
|
+
QPushButton,
|
|
40
|
+
QVBoxLayout,
|
|
41
|
+
QWidget,
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
from MDANSE.MLogging import LOG
|
|
45
|
+
|
|
46
|
+
# I think that a Trajectory Converter should, in general,
|
|
47
|
+
# create a Wizard and not a single Dialog.
|
|
48
|
+
# This way LAMMPS could give the user a chance to verify which
|
|
49
|
+
# elements were in the system, instead of just failing.
|
|
50
|
+
# The idea is similar to Origin and the way Origin creates
|
|
51
|
+
# a lengthy wizard interface just to load data from a file.
|
|
52
|
+
# The wizard should have a number of stages, which can be
|
|
53
|
+
# used or left empty.
|
|
54
|
+
|
|
55
|
+
# I need to have several stages of processing
|
|
56
|
+
# 1. The initial Dialog is created based on settings from the Converter
|
|
57
|
+
# 2. The user specifies the input files
|
|
58
|
+
# 3. The converter tries to get as much information as possible from the files
|
|
59
|
+
# 4. The information gathered is shown to the user,
|
|
60
|
+
# with a possibility of correcting the entries.
|
|
61
|
+
# 5. The corrected parameters are passed to the converter, and the job is started.
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class WhitespaceValidator(QValidator):
|
|
65
|
+
"""Does not allow empty or whitespace names."""
|
|
66
|
+
|
|
67
|
+
EXCLUDED_CHARACTERS = [" ", "\n", "\t", "\\"]
|
|
68
|
+
|
|
69
|
+
def __init__(self, *args, default_name: str = "DEFAULT", **kwargs):
|
|
70
|
+
super().__init__(*args, **kwargs)
|
|
71
|
+
self.default_name = default_name
|
|
72
|
+
|
|
73
|
+
def validate(self, input_string: str, position: int):
|
|
74
|
+
state = (
|
|
75
|
+
QValidator.State.Invalid
|
|
76
|
+
if not input_string
|
|
77
|
+
or any(char in input_string for char in self.EXCLUDED_CHARACTERS)
|
|
78
|
+
else QValidator.State.Acceptable
|
|
79
|
+
)
|
|
80
|
+
return state, input_string, position
|
|
81
|
+
|
|
82
|
+
def fixup(self, invalid_string: str):
|
|
83
|
+
invalid_string = self.default_name
|
|
84
|
+
return super().fixup(invalid_string)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
# the following code was useful at first - but could it be replaced by
|
|
88
|
+
# the widgets and dialogs above?
|
|
89
|
+
# The InputVariable/InputDialog combo seems to be offering a subset
|
|
90
|
+
# of what InputFactory and GeneralInput can do.
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
class InputVariable(QObject):
|
|
94
|
+
"""A general-purpose input field, used by the InputDialog."""
|
|
95
|
+
|
|
96
|
+
def __init__(self, *args, input_dict: dict | None = None, **kwargs):
|
|
97
|
+
super().__init__(*args, **kwargs)
|
|
98
|
+
|
|
99
|
+
self.label = "Variable"
|
|
100
|
+
self.keyval = "var1"
|
|
101
|
+
self.format = float
|
|
102
|
+
self.value = 0.0
|
|
103
|
+
self.helper_dialog = None
|
|
104
|
+
self.tooltip = ""
|
|
105
|
+
self.invalid_tooltip = ""
|
|
106
|
+
self.placeholder = ""
|
|
107
|
+
for key, item in input_dict.items():
|
|
108
|
+
self.__setattr__(str(key), item)
|
|
109
|
+
|
|
110
|
+
if isinstance(self.value, list):
|
|
111
|
+
self.widget = QComboBox
|
|
112
|
+
else:
|
|
113
|
+
self.widget = QLineEdit
|
|
114
|
+
|
|
115
|
+
self.input_widget = None
|
|
116
|
+
|
|
117
|
+
def returnValue(self) -> float | int | str:
|
|
118
|
+
"""
|
|
119
|
+
Returns
|
|
120
|
+
-------
|
|
121
|
+
Union[float, int, str]
|
|
122
|
+
The results from the input widget.
|
|
123
|
+
"""
|
|
124
|
+
if isinstance(self.input_widget, QComboBox):
|
|
125
|
+
text = self.input_widget.currentText()
|
|
126
|
+
else:
|
|
127
|
+
text = self.input_widget.text()
|
|
128
|
+
try:
|
|
129
|
+
result = self.format(text)
|
|
130
|
+
except ValueError:
|
|
131
|
+
result = text
|
|
132
|
+
return result
|
|
133
|
+
|
|
134
|
+
def inputValid(self) -> bool:
|
|
135
|
+
"""Should be overridden to allow for more complex input
|
|
136
|
+
validation checks.
|
|
137
|
+
|
|
138
|
+
Returns
|
|
139
|
+
-------
|
|
140
|
+
bool
|
|
141
|
+
True if the input is valid.
|
|
142
|
+
"""
|
|
143
|
+
return True
|
|
144
|
+
|
|
145
|
+
def setValidState(self):
|
|
146
|
+
"""The input widget is return to its valid state."""
|
|
147
|
+
if not self.input_widget or isinstance(self.input_widget, QComboBox):
|
|
148
|
+
return
|
|
149
|
+
|
|
150
|
+
self.input_widget.setToolTip(self.tooltip)
|
|
151
|
+
self.input_widget.setPalette(QPalette())
|
|
152
|
+
|
|
153
|
+
def setInvalidState(self):
|
|
154
|
+
"""Puts the input widget into an invalid state. The widget
|
|
155
|
+
background is changed."""
|
|
156
|
+
if not self.input_widget or isinstance(self.input_widget, QComboBox):
|
|
157
|
+
return
|
|
158
|
+
|
|
159
|
+
self.input_widget.setToolTip(self.invalid_tooltip)
|
|
160
|
+
pallette = QPalette()
|
|
161
|
+
pallette.setColor(QPalette.Base, Qt.GlobalColor.red)
|
|
162
|
+
self.input_widget.setPalette(pallette)
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
class InputDialog(QDialog):
|
|
166
|
+
"""A simple dialog designed to contain a number of input fields.
|
|
167
|
+
It is used by the UnitsEditor and ElementsDatabaseEditor.
|
|
168
|
+
"""
|
|
169
|
+
|
|
170
|
+
got_values = Signal(dict)
|
|
171
|
+
|
|
172
|
+
def __init__(
|
|
173
|
+
self, *args, fields: Iterable[InputVariable] = (), title: str = "", **kwargs
|
|
174
|
+
):
|
|
175
|
+
super().__init__(*args, **kwargs)
|
|
176
|
+
|
|
177
|
+
self.setModal(True)
|
|
178
|
+
self.setWindowTitle(title)
|
|
179
|
+
|
|
180
|
+
self.fields = fields # we need to store it for later
|
|
181
|
+
layout = QVBoxLayout(self)
|
|
182
|
+
self.setLayout(layout)
|
|
183
|
+
# now some basic elements
|
|
184
|
+
var_base = QWidget(self)
|
|
185
|
+
var_layout = QFormLayout(var_base)
|
|
186
|
+
var_base.setLayout(var_layout)
|
|
187
|
+
button_base = QWidget(self)
|
|
188
|
+
button_layout = QHBoxLayout(button_base)
|
|
189
|
+
button_base.setLayout(button_layout)
|
|
190
|
+
layout.addWidget(var_base)
|
|
191
|
+
layout.addWidget(button_base)
|
|
192
|
+
# the most important part: handling the variables
|
|
193
|
+
for var in fields:
|
|
194
|
+
label = var.label
|
|
195
|
+
format = var.format
|
|
196
|
+
value = var.value
|
|
197
|
+
widget = var.widget
|
|
198
|
+
_helper_dialog = var.helper_dialog
|
|
199
|
+
placeholder = var.placeholder
|
|
200
|
+
# set up widgets
|
|
201
|
+
temp_base = QWidget(var_base)
|
|
202
|
+
temp_layout = QHBoxLayout(temp_base)
|
|
203
|
+
temp_base.setLayout(temp_layout)
|
|
204
|
+
widget_instance = widget(var_base)
|
|
205
|
+
if isinstance(value, list):
|
|
206
|
+
widget_instance.addItems(value)
|
|
207
|
+
else:
|
|
208
|
+
if format is int:
|
|
209
|
+
validator = QIntValidator(temp_base)
|
|
210
|
+
elif format is float:
|
|
211
|
+
validator = QDoubleValidator(temp_base)
|
|
212
|
+
elif hasattr(var, "default_text"):
|
|
213
|
+
validator = WhitespaceValidator(
|
|
214
|
+
temp_base, default_name=var.default_text
|
|
215
|
+
)
|
|
216
|
+
else:
|
|
217
|
+
validator = None
|
|
218
|
+
widget_instance.setText(str(value))
|
|
219
|
+
widget_instance.setPlaceholderText(str(placeholder))
|
|
220
|
+
if validator is not None:
|
|
221
|
+
widget_instance.setValidator(validator)
|
|
222
|
+
widget_instance.textChanged.connect(self.check_values)
|
|
223
|
+
temp_layout.addWidget(widget_instance)
|
|
224
|
+
var.input_widget = widget_instance
|
|
225
|
+
var_layout.addRow(label, temp_base)
|
|
226
|
+
# optinally we can add other buttons here...
|
|
227
|
+
#
|
|
228
|
+
# final button, always there
|
|
229
|
+
self.button = QPushButton("Accept!", self)
|
|
230
|
+
self.button.clicked.connect(self.accept)
|
|
231
|
+
self.accepted.connect(self.return_values)
|
|
232
|
+
button_layout.addWidget(self.button)
|
|
233
|
+
self.check_values()
|
|
234
|
+
|
|
235
|
+
@Slot()
|
|
236
|
+
def return_values(self):
|
|
237
|
+
"""Emits the results from the input widgets."""
|
|
238
|
+
result = {}
|
|
239
|
+
for var in self.fields:
|
|
240
|
+
result[var.keyval] = var.returnValue()
|
|
241
|
+
self.got_values.emit(result)
|
|
242
|
+
|
|
243
|
+
def check_values(self):
|
|
244
|
+
"""Checks if the values in the input widget are valid. If not
|
|
245
|
+
the Accept! button is deactivated and the widget may change
|
|
246
|
+
color to alert the user.
|
|
247
|
+
"""
|
|
248
|
+
for var in self.fields:
|
|
249
|
+
if not var.inputValid():
|
|
250
|
+
self.button.setEnabled(False)
|
|
251
|
+
var.setInvalidState()
|
|
252
|
+
return
|
|
253
|
+
var.setValidState()
|
|
254
|
+
self.button.setEnabled(True)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: MDANSE_GUI
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.1
|
|
4
4
|
Summary: MDANSE GUI package - the graphical interface for MDANSE
|
|
5
5
|
Maintainer-email: Maciej Bartkowiak <maciej.bartkowiak@stfc.ac.uk>, "Chi Y. Cheng" <chi.cheng@stfc.ac.uk>, Jacob Wilkins <jacob.wilkins@stfc.ac.uk>
|
|
6
6
|
License: GNU GENERAL PUBLIC LICENSE
|
|
@@ -724,19 +724,6 @@ Molecular Dynamics Analysis for Neutron Scattering Experiments (MDANSE) software
|
|
|
724
724
|
|
|
725
725
|
The GUI depends on the [MDANSE package](https://pypi.org/project/MDANSE).
|
|
726
726
|
|
|
727
|
-
## Version information
|
|
728
|
-
|
|
729
|
-
This is the first release of MDANSE_GUI 2.0.0.
|
|
730
|
-
|
|
731
|
-
> [!NOTE]
|
|
732
|
-
> Considering the large number of different MD engines and analysis types,
|
|
733
|
-
> it is still possible that some conversion or analysis runs will not
|
|
734
|
-
> produce the expected results. Please report any problems
|
|
735
|
-
> you experience while using MDANSE by adding them to the
|
|
736
|
-
> [GitHub issue tracker](https://github.com/ISISNeutronMuon/MDANSE/issues).
|
|
737
|
-
> You can also send a message to MDANSE-help@stfc.ac.uk to get in touch
|
|
738
|
-
> with MDANSE developers.
|
|
739
|
-
|
|
740
727
|
## Quick start: installation
|
|
741
728
|
|
|
742
729
|
We recommend that you install MDANSE in a Python virtual environment.
|
|
Binary file
|