From 8d148b639b3c08d6f65953eca86b877a71284e6b Mon Sep 17 00:00:00 2001 From: dominik Date: Thu, 20 Oct 2022 17:23:15 +0200 Subject: [PATCH] BUGFIX: VFT; change to src layout --- bin/evaluate.py | 6 +- doc/Makefile | 2 +- doc/examples/nmr/plot_RelaxationEvaluation.py | 15 +- doc/source/_static/fit_dialog.png | Bin 47372 -> 0 bytes doc/source/_templates/autosummary/class.rst | 45 +- doc/source/api/distributions.rst | 3 - doc/source/api/index.rst | 1 + doc/source/conf.py | 38 +- doc/source/index.rst | 10 +- doc/source/nmr/pake.rst | 3 +- doc/source/user_guide/fit.rst | 4 - doc/source/user_guide/index.rst | 8 +- doc/source/user_guide/read.rst | 19 - nmreval/distributions/gengamma.py | 111 ----- nmreval/gui_qt/_py/fitcreationdialog.py | 189 -------- .../gui_qt/fit/function_creation_dialog.py | 238 ---------- nmreval/math/wideline.py | 357 -------------- nmreval/models/gengamma.py | 268 ----------- requirements.txt | 4 +- resources/_ui/fitcreationdialog.ui | 419 ---------------- {nmreval => src}/gui_qt/Qt.py | 2 +- {nmreval => src}/gui_qt/__init__.py | 3 +- {nmreval => src}/gui_qt/_py/__init__.py | 0 .../gui_qt/_py/agroptiondialog.py | 0 {nmreval => src}/gui_qt/_py/apod_dialog.py | 0 {nmreval => src}/gui_qt/_py/asciidialog.py | 0 .../gui_qt/_py/axisConfigTemplate.py | 0 .../gui_qt/_py/baseline_dialog.py | 0 {nmreval => src}/gui_qt/_py/basewindow.py | 0 {nmreval => src}/gui_qt/_py/bdsdialog.py | 0 {nmreval => src}/gui_qt/_py/color_palette.py | 0 .../gui_qt/_py/coupling_calculator.py | 0 .../gui_qt/_py/coupling_t1_from_tau.py | 0 {nmreval => src}/gui_qt/_py/datawidget.py | 0 {nmreval => src}/gui_qt/_py/dscfile_dialog.py | 0 .../gui_qt/_py/editsignalwidget.py | 0 .../gui_qt/_py/eval_expr_dialog.py | 0 {nmreval => src}/gui_qt/_py/evalexpression.py | 0 .../gui_qt/_py/expandablewidget.py | 0 .../gui_qt/_py/exportConfigTemplate.py | 0 {nmreval => src}/gui_qt/_py/fcreader.py | 0 {nmreval => src}/gui_qt/_py/filedialog.py | 0 src/gui_qt/_py/fitcreationdialog.py | 77 +++ {nmreval => src}/gui_qt/_py/fitdialog.py | 0 .../gui_qt/_py/fitdialog_window.py | 0 .../gui_qt/_py/fitfunctionwidget.py | 0 {nmreval => src}/gui_qt/_py/fitfuncwidget.py | 0 .../gui_qt/_py/fitfuncwidget_old.py | 0 .../gui_qt/_py/fitmodelfixwidget.py | 0 {nmreval => src}/gui_qt/_py/fitmodelwidget.py | 0 .../gui_qt/_py/fitparametertable.py | 0 .../gui_qt/_py/fitparameterwidget.py | 0 {nmreval => src}/gui_qt/_py/fitresult.py | 0 {nmreval => src}/gui_qt/_py/ftdialog.py | 0 .../gui_qt/_py/function_tree_widget.py | 0 {nmreval => src}/gui_qt/_py/gol.py | 0 {nmreval => src}/gui_qt/_py/gracemsgdialog.py | 0 {nmreval => src}/gui_qt/_py/gracereader.py | 0 {nmreval => src}/gui_qt/_py/graph.py | 0 .../gui_qt/_py/guidelinewidget.py | 0 {nmreval => src}/gui_qt/_py/hdftree.py | 0 .../gui_qt/_py/integral_widget.py | 0 .../gui_qt/_py/integratederive_dialog.py | 0 .../gui_qt/_py/interpol_dialog.py | 0 .../gui_qt/_py/lineedit_dialog.py | 0 {nmreval => src}/gui_qt/_py/mean_form.py | 0 {nmreval => src}/gui_qt/_py/meandialog.py | 0 {nmreval => src}/gui_qt/_py/modelwidget.py | 0 {nmreval => src}/gui_qt/_py/move_dialog.py | 0 .../gui_qt/_py/namespace_widget.py | 0 .../gui_qt/_py/option_selection.py | 0 {nmreval => src}/gui_qt/_py/parameterform.py | 0 .../gui_qt/_py/phase_corr_dialog.py | 0 .../gui_qt/_py/plotConfigTemplate.py | 0 {nmreval => src}/gui_qt/_py/pokemon.py | 0 {nmreval => src}/gui_qt/_py/propwidget.py | 0 {nmreval => src}/gui_qt/_py/ptstab.py | 0 {nmreval => src}/gui_qt/_py/qfiledialog.py | 0 .../gui_qt/_py/save_fit_parameter.py | 0 .../gui_qt/_py/save_fitmodel_dialog.py | 0 {nmreval => src}/gui_qt/_py/save_options.py | 0 {nmreval => src}/gui_qt/_py/saveoptions.py | 0 {nmreval => src}/gui_qt/_py/sdmodelwidget.py | 0 .../gui_qt/_py/selection_widget.py | 0 .../gui_qt/_py/setbyfunction_dialog.py | 0 .../gui_qt/_py/shift_scale_dialog.py | 2 +- {nmreval => src}/gui_qt/_py/skipdialog.py | 0 {nmreval => src}/gui_qt/_py/smoothdialog.py | 0 {nmreval => src}/gui_qt/_py/t1_calc_dialog.py | 0 {nmreval => src}/gui_qt/_py/t1_dock.py | 0 .../gui_qt/_py/t1_tau_calculation.py | 0 {nmreval => src}/gui_qt/_py/t1dialog.py | 0 {nmreval => src}/gui_qt/_py/tntdialog.py | 0 {nmreval => src}/gui_qt/_py/typeconversion.py | 0 {nmreval => src}/gui_qt/_py/untitled.py | 0 {nmreval => src}/gui_qt/_py/userfitassist.py | 0 .../gui_qt/_py/usermodeleditor.py | 0 {nmreval => src}/gui_qt/_py/valueeditor.py | 0 {nmreval => src}/gui_qt/data/__init__.py | 0 {nmreval => src}/gui_qt/data/container.py | 19 +- {nmreval => src}/gui_qt/data/conversion.py | 0 .../gui_qt/data/datawidget/__init__.py | 0 .../gui_qt/data/datawidget/datawidget.py | 1 + .../gui_qt/data/datawidget/properties.py | 0 .../gui_qt/data/integral_widget.py | 0 .../gui_qt/data/interpolate_dialog.py | 0 {nmreval => src}/gui_qt/data/plot_dialog.py | 6 +- {nmreval => src}/gui_qt/data/point_select.py | 2 +- {nmreval => src}/gui_qt/data/shift_graphs.py | 3 +- .../gui_qt/data/signaledit/__init__.py | 0 .../gui_qt/data/signaledit/baseline_dialog.py | 8 +- .../data/signaledit/editsignalwidget.py | 6 +- .../gui_qt/data/signaledit/phase_dialog.py | 12 +- .../gui_qt/data/valueeditwidget.py | 4 +- {nmreval => src}/gui_qt/fit/__init__.py | 0 {nmreval => src}/gui_qt/fit/fit_forms.py | 9 +- {nmreval => src}/gui_qt/fit/fit_parameter.py | 3 +- {nmreval => src}/gui_qt/fit/fitfunction.py | 19 +- {nmreval => src}/gui_qt/fit/fitwindow.py | 5 +- src/gui_qt/fit/function_creation_dialog.py | 449 ++++++++++++++++++ {nmreval => src}/gui_qt/fit/result.py | 4 +- {nmreval => src}/gui_qt/graphs/__init__.py | 0 {nmreval => src}/gui_qt/graphs/graphwindow.py | 14 +- {nmreval => src}/gui_qt/graphs/guide_lines.py | 0 {nmreval => src}/gui_qt/graphs/movedialog.py | 0 {nmreval => src}/gui_qt/io/__init__.py | 0 {nmreval => src}/gui_qt/io/asciireader.py | 2 +- {nmreval => src}/gui_qt/io/bdsreader.py | 2 +- {nmreval => src}/gui_qt/io/dscreader.py | 5 +- {nmreval => src}/gui_qt/io/exporters.py | 4 +- {nmreval => src}/gui_qt/io/fcbatchreader.py | 6 +- {nmreval => src}/gui_qt/io/filedialog.py | 0 {nmreval => src}/gui_qt/io/filereaders.py | 8 +- {nmreval => src}/gui_qt/io/gracereader.py | 8 +- {nmreval => src}/gui_qt/io/hdfreader.py | 2 +- {nmreval => src}/gui_qt/io/nmrreader.py | 2 +- .../gui_qt/io/save_fitparameter.py | 0 {nmreval => src}/gui_qt/io/tntreader.py | 2 +- {nmreval => src}/gui_qt/lib/__init__.py | 0 {nmreval => src}/gui_qt/lib/codeeditor.py | 0 {nmreval => src}/gui_qt/lib/color_dialog.py | 5 +- {nmreval => src}/gui_qt/lib/configurations.py | 4 +- {nmreval => src}/gui_qt/lib/decorators.py | 0 {nmreval => src}/gui_qt/lib/delegates.py | 8 +- .../gui_qt/lib/expandablewidget.py | 0 {nmreval => src}/gui_qt/lib/forms.py | 2 +- {nmreval => src}/gui_qt/lib/gol.py | 0 {nmreval => src}/gui_qt/lib/namespace.py | 11 +- {nmreval => src}/gui_qt/lib/pg_objects.py | 7 +- {nmreval => src}/gui_qt/lib/randpok.py | 0 {nmreval => src}/gui_qt/lib/spinboxes.py | 0 {nmreval => src}/gui_qt/lib/stuff.py | 0 {nmreval => src}/gui_qt/lib/styles.py | 0 {nmreval => src}/gui_qt/lib/tables.py | 0 {nmreval => src}/gui_qt/lib/undos.py | 0 .../gui_qt/lib/usermodeleditor.py | 0 {nmreval => src}/gui_qt/lib/utils.py | 0 {nmreval => src}/gui_qt/main/__init__.py | 0 {nmreval => src}/gui_qt/main/mainwindow.py | 10 +- {nmreval => src}/gui_qt/main/management.py | 18 +- {nmreval/io => src/gui_qt/math}/__init__.py | 0 {nmreval => src}/gui_qt/math/bootstrap.py | 0 {nmreval => src}/gui_qt/math/evaluation.py | 1 - .../gui_qt/math/integrate_derive.py | 0 {nmreval => src}/gui_qt/math/interpol.py | 0 {nmreval => src}/gui_qt/math/mean_dialog.py | 3 +- {nmreval => src}/gui_qt/math/skipping.py | 0 {nmreval => src}/gui_qt/math/smooth.py | 0 {nmreval/lib => src/gui_qt/nmr}/__init__.py | 0 {nmreval => src}/gui_qt/nmr/coupling_calc.py | 4 +- {nmreval => src}/gui_qt/nmr/t1_from_tau.py | 12 +- {nmreval => src}/gui_qt/nmr/t1widget.py | 10 +- {nmreval => src/nmreval}/__init__.py | 0 {nmreval => src/nmreval}/bds/__init__.py | 0 {nmreval => src/nmreval}/configs.py | 0 {nmreval => src/nmreval}/data/__init__.py | 0 {nmreval => src/nmreval}/data/bds.py | 0 {nmreval => src/nmreval}/data/dsc.py | 0 {nmreval => src/nmreval}/data/nmr.py | 1 - {nmreval => src/nmreval}/data/points.py | 31 +- {nmreval => src/nmreval}/data/signals.py | 5 +- .../nmreval}/distributions/__init__.py | 1 - .../nmreval}/distributions/base.py | 6 +- .../nmreval}/distributions/colecole.py | 39 +- .../nmreval}/distributions/coledavidson.py | 9 +- .../nmreval}/distributions/debye.py | 4 +- .../nmreval}/distributions/energy.py | 47 +- src/nmreval/distributions/gengamma.py | 178 +++++++ .../nmreval}/distributions/havriliaknegami.py | 24 +- .../nmreval}/distributions/intermolecular.py | 0 {nmreval => src/nmreval}/distributions/kww.py | 0 .../nmreval}/distributions/loggaussian.py | 2 - {nmreval/math => src/nmreval/dsc}/__init__.py | 0 {nmreval => src/nmreval}/dsc/calibration.py | 5 +- .../nmreval}/dsc/dsc_calibration_fast_neu.py | 0 {nmreval => src/nmreval}/fit/__init__.py | 0 {nmreval => src/nmreval}/fit/_meta.py | 6 +- {nmreval => src/nmreval}/fit/data.py | 0 {nmreval => src/nmreval}/fit/minimizer.py | 2 +- {nmreval => src/nmreval}/fit/model.py | 0 {nmreval => src/nmreval}/fit/parameter.py | 0 {nmreval => src/nmreval}/fit/result.py | 2 +- {resources => src/nmreval/io}/__init__.py | 0 {nmreval => src/nmreval}/io/asciireader.py | 0 {nmreval => src/nmreval}/io/bds_reader.py | 5 +- {nmreval => src/nmreval}/io/dsc.py | 1 + {nmreval => src/nmreval}/io/fcbatchreader.py | 129 ++++- {nmreval => src/nmreval}/io/graceeditor.py | 9 +- {nmreval => src/nmreval}/io/hdfreader.py | 2 + {nmreval => src/nmreval}/io/merge_agr.py | 1 - {nmreval => src/nmreval}/io/nmrreader.py | 9 +- {nmreval => src/nmreval}/io/read_old_nmr.py | 0 {nmreval => src/nmreval}/io/sessionwriter.py | 0 {nmreval => src/nmreval}/io/tntreader.py | 0 .../icons => src/nmreval/lib}/__init__.py | 0 {nmreval => src/nmreval}/lib/colors.py | 0 {nmreval => src/nmreval}/lib/decorator.py | 0 {nmreval => src/nmreval}/lib/importer.py | 8 +- {nmreval => src/nmreval}/lib/lines.py | 0 {nmreval => src/nmreval}/lib/logger.py | 0 {nmreval => src/nmreval}/lib/symbols.py | 2 +- {nmreval => src/nmreval}/lib/utils.py | 0 src/nmreval/math/__init__.py | 32 ++ {nmreval => src/nmreval}/math/apodization.py | 40 ++ {nmreval => src/nmreval}/math/interpol.py | 0 {nmreval => src/nmreval}/math/kww.py | 0 {nmreval => src/nmreval}/math/logfourier.py | 0 .../nmreval}/math/mittagleffler.py | 6 +- {nmreval => src/nmreval}/math/orientations.py | 0 {nmreval => src/nmreval}/math/pca.py | 0 {nmreval => src/nmreval}/math/smooth.py | 0 {nmreval => src/nmreval}/models/__init__.py | 0 {nmreval => src/nmreval}/models/basic.py | 0 {nmreval => src/nmreval}/models/bds.py | 0 .../nmreval}/models/correlationfuncs.py | 0 {nmreval => src/nmreval}/models/diffusion.py | 0 .../nmreval}/models/fieldcycling.py | 0 {nmreval => src/nmreval}/models/relaxation.py | 0 {nmreval => src/nmreval}/models/spectrum.py | 6 +- {nmreval => src/nmreval}/models/stimecho.py | 2 +- .../nmreval}/models/temperature.py | 8 +- .../nmreval}/models/transitions.py | 0 {nmreval => src/nmreval}/models/usermodels.py | 0 {nmreval => src/nmreval}/models/wideline.py | 0 {nmreval => src/nmreval}/nmr/__init__.py | 0 {nmreval => src/nmreval}/nmr/coupling.py | 0 {nmreval => src/nmreval}/nmr/fc_eval.py | 0 {nmreval => src/nmreval}/nmr/relaxation.py | 9 +- {nmreval => src/nmreval}/utils/__init__.py | 0 {nmreval => src/nmreval}/utils/constants.py | 0 {nmreval => src/nmreval}/utils/exception.py | 0 .../nmreval}/utils/pca_demo_pcs.py | 0 {nmreval => src/nmreval}/utils/pokemon.json | 0 {nmreval => src/nmreval}/utils/text.py | 0 {nmreval => src/nmreval}/utils/utils.py | 0 {nmreval => src/nmreval}/version.py | 0 {resources => src/resources}/Default.agr | 0 {resources/nmr => src/resources}/__init__.py | 0 {resources => src/resources}/_rc/axes.png | Bin .../resources}/_rc/blackwhite.png | Bin .../resources}/_rc/blackwhite.svg | 0 {resources => src/resources}/_rc/cat.png | Bin {resources => src/resources}/_rc/colors.png | Bin {resources => src/resources}/_rc/colors.svg | 0 .../resources}/_rc/cut_region.png | Bin .../resources}/_rc/eval_button.png | Bin .../resources}/_rc/fit_preview.png | Bin .../resources}/_rc/fit_region.png | Bin {resources => src/resources}/_rc/grid.png | Bin {resources => src/resources}/_rc/grid.svg | 0 {resources => src/resources}/_rc/imag.png | Bin {resources => src/resources}/_rc/imag.svg | 0 {resources => src/resources}/_rc/images.qrc | 0 {resources => src/resources}/_rc/left.png | Bin {resources => src/resources}/_rc/logo.png | Bin {resources => src/resources}/_rc/mean.png | Bin {resources => src/resources}/_rc/mouse.png | Bin .../resources}/_rc/open_session.png | Bin .../resources}/_rc/path48-3-5-6-2.png | Bin .../resources}/_rc/properties.png | Bin .../resources}/_rc/punktdings.png | Bin {resources => src/resources}/_rc/real.png | Bin {resources => src/resources}/_rc/real.svg | 0 {resources => src/resources}/_rc/right.png | Bin {resources => src/resources}/_rc/sort.png | Bin {resources => src/resources}/_rc/xlog.png | Bin {resources => src/resources}/_rc/xlog.svg | 0 {resources => src/resources}/_rc/ylog.png | Bin {resources => src/resources}/_rc/ylog.svg | 0 .../resources}/_ui/agroptiondialog.ui | 0 .../resources}/_ui/apod_dialog.ui | 0 .../resources}/_ui/asciidialog.ui | 0 .../resources}/_ui/axisConfigTemplate.ui | 0 .../resources}/_ui/baseline_dialog.ui | 0 .../resources}/_ui/basewindow.ui | 0 {resources => src/resources}/_ui/bdsdialog.ui | 0 .../resources}/_ui/color_palette.ui | 0 .../resources}/_ui/coupling_calculator.ui | 0 .../resources}/_ui/coupling_t1_from_tau.ui | 0 .../resources}/_ui/datawidget.ui | 0 .../resources}/_ui/dscfile_dialog.ui | 0 .../resources}/_ui/editsignalwidget.ui | 0 .../resources}/_ui/eval_expr_dialog.ui | 0 .../resources}/_ui/evalexpression.ui | 0 .../resources}/_ui/expandablewidget.ui | 0 .../resources}/_ui/exportConfigTemplate.ui | 0 {resources => src/resources}/_ui/fcreader.ui | 0 .../resources}/_ui/filedialog.ui | 0 src/resources/_ui/fitcreationdialog.ui | 150 ++++++ {resources => src/resources}/_ui/fitdialog.ui | 0 .../resources}/_ui/fitdialog_window.ui | 0 .../resources}/_ui/fitfunctionwidget.ui | 0 .../resources}/_ui/fitfuncwidget.ui | 0 .../resources}/_ui/fitfuncwidget_old.ui | 0 .../resources}/_ui/fitmodelfixwidget.ui | 0 .../resources}/_ui/fitmodelwidget.ui | 0 .../resources}/_ui/fitparametertable.ui | 0 .../resources}/_ui/fitparameterwidget.ui | 0 {resources => src/resources}/_ui/fitresult.ui | 0 {resources => src/resources}/_ui/ftdialog.ui | 0 .../resources}/_ui/function_tree_widget.ui | 0 {resources => src/resources}/_ui/gol.ui | 0 .../resources}/_ui/gracemsgdialog.ui | 0 .../resources}/_ui/gracereader.ui | 0 {resources => src/resources}/_ui/graph.ui | 0 .../resources}/_ui/guidelinewidget.ui | 0 {resources => src/resources}/_ui/hdftree.ui | 0 .../resources}/_ui/integral_widget.ui | 0 .../resources}/_ui/integratederive_dialog.ui | 0 .../resources}/_ui/interpol_dialog.ui | 0 .../resources}/_ui/lineedit_dialog.ui | 0 {resources => src/resources}/_ui/mean_form.ui | 0 .../resources}/_ui/meandialog.ui | 0 .../resources}/_ui/modelwidget.ui | 0 .../resources}/_ui/move_dialog.ui | 0 .../resources}/_ui/namespace_widget.ui | 0 .../resources}/_ui/option_selection.ui | 0 .../resources}/_ui/parameterform.ui | 0 .../resources}/_ui/phase_corr_dialog.ui | 0 .../resources}/_ui/plotConfigTemplate.ui | 0 {resources => src/resources}/_ui/pokemon.ui | 0 .../resources}/_ui/propwidget.ui | 0 {resources => src/resources}/_ui/ptstab.ui | 0 .../resources}/_ui/qfiledialog.ui | 0 .../resources}/_ui/save_fit_parameter.ui | 0 .../resources}/_ui/save_fitmodel_dialog.ui | 0 .../resources}/_ui/save_options.ui | 0 .../resources}/_ui/saveoptions.ui | 0 .../resources}/_ui/sdmodelwidget.ui | 0 .../resources}/_ui/selection_widget.ui | 0 .../resources}/_ui/setbyfunction_dialog.ui | 0 .../resources}/_ui/shift_scale_dialog.ui | 2 +- .../resources}/_ui/skipdialog.ui | 0 .../resources}/_ui/smoothdialog.ui | 0 .../resources}/_ui/t1_calc_dialog.ui | 0 {resources => src/resources}/_ui/t1_dock.ui | 0 .../resources}/_ui/t1_tau_calculation.ui | 0 {resources => src/resources}/_ui/t1dialog.ui | 0 {resources => src/resources}/_ui/tntdialog.ui | 0 .../resources}/_ui/typeconversion.ui | 0 {resources => src/resources}/_ui/untitled.ui | 0 .../resources}/_ui/userfitassist.ui | 0 .../resources}/_ui/usermodeleditor.ui | 0 .../resources}/_ui/valueeditor.ui | 0 src/resources/icons/__init__.py | 0 {resources => src/resources}/icons/icons.json | 0 {resources => src/resources}/icons/logo.png | Bin .../resources}/icons/normal_light/__init__.py | 0 .../icons/normal_light/blackwhite.png | Bin .../resources}/icons/normal_light/colors.png | Bin .../resources}/icons/normal_light/concat.png | Bin .../resources}/icons/normal_light/errors.png | Bin .../icons/normal_light/eval_expression.png | Bin .../resources}/icons/normal_light/fit.png | Bin .../icons/normal_light/fit_region.png | Bin .../icons/normal_light/geteilt_icon.png | Bin .../resources}/icons/normal_light/grid.png | Bin .../resources}/icons/normal_light/imag.png | Bin .../resources}/icons/normal_light/left.png | Bin .../resources}/icons/normal_light/legend.png | Bin .../icons/normal_light/mal_icon.png | Bin .../resources}/icons/normal_light/mean.png | Bin .../icons/normal_light/messdings.png | Bin .../icons/normal_light/minus_icon.png | Bin .../resources}/icons/normal_light/mouse.png | Bin .../resources}/icons/normal_light/new.png | Bin .../resources}/icons/normal_light/normal.png | Bin .../resources}/icons/normal_light/open.png | Bin .../resources}/icons/normal_light/plus.png | Bin .../icons/normal_light/plus_icon.png | Bin .../icons/normal_light/points_pick.png | Bin .../resources}/icons/normal_light/real.png | Bin .../resources}/icons/normal_light/right.png | Bin .../resources}/icons/normal_light/save.png | Bin .../icons/normal_light/save_session.png | Bin .../resources}/icons/normal_light/scaling.png | Bin .../resources}/icons/normal_light/sort.png | Bin .../icons/normal_light/t1_from_tau.png | Bin .../icons/normal_light/tau_from_t1.png | Bin .../resources}/icons/normal_light/values.png | Bin .../resources}/icons/normal_light/xlog.png | Bin .../resources}/icons/normal_light/ylog.png | Bin .../icons/pokemon_light/__init__.py | 0 .../icons/pokemon_light/blackwhite.png | Bin .../resources}/icons/pokemon_light/colors.png | Bin .../resources}/icons/pokemon_light/concat.png | Bin .../resources}/icons/pokemon_light/errors.png | Bin .../icons/pokemon_light/eval_expression.png | Bin .../resources}/icons/pokemon_light/fit.png | Bin .../icons/pokemon_light/fit_region.png | Bin .../icons/pokemon_light/geteilt_icon.png | Bin .../resources}/icons/pokemon_light/grid.png | Bin .../resources}/icons/pokemon_light/imag.png | Bin .../resources}/icons/pokemon_light/left.png | Bin .../resources}/icons/pokemon_light/legend.png | Bin .../icons/pokemon_light/mal_icon.png | Bin .../resources}/icons/pokemon_light/mean.png | Bin .../icons/pokemon_light/messdings.png | Bin .../icons/pokemon_light/minus_icon.png | Bin .../resources}/icons/pokemon_light/mouse.png | Bin .../resources}/icons/pokemon_light/new.png | Bin .../resources}/icons/pokemon_light/normal.png | Bin .../resources}/icons/pokemon_light/open.png | Bin .../resources}/icons/pokemon_light/plus.png | Bin .../icons/pokemon_light/plus_icon.png | Bin .../icons/pokemon_light/points_pick.png | Bin .../resources}/icons/pokemon_light/real.png | Bin .../resources}/icons/pokemon_light/right.png | Bin .../resources}/icons/pokemon_light/save.png | Bin .../icons/pokemon_light/save_session.png | Bin .../icons/pokemon_light/scaling.png | Bin .../resources}/icons/pokemon_light/sort.png | Bin .../icons/pokemon_light/t1_from_tau.png | Bin .../icons/pokemon_light/tau_from_t1.png | Bin .../resources}/icons/pokemon_light/values.png | Bin .../resources}/icons/pokemon_light/xlog.png | Bin .../resources}/icons/pokemon_light/ylog.png | Bin {resources => src/resources}/icons/style.qss | 0 {resources => src/resources}/logo.png | Bin .../resources}/nmr/Cole-Cole_min.dat | 0 .../resources}/nmr/Cole-Davidson_min.dat | 0 {resources => src/resources}/nmr/KWW_min.dat | 0 .../resources}/nmr/Log-Gaussian_min.dat | 0 {resources => src/resources}/nmr/T1_min.npz | Bin src/resources/nmr/__init__.py | 0 445 files changed, 1387 insertions(+), 1920 deletions(-) delete mode 100644 doc/source/_static/fit_dialog.png delete mode 100644 doc/source/user_guide/read.rst delete mode 100644 nmreval/distributions/gengamma.py delete mode 100644 nmreval/gui_qt/_py/fitcreationdialog.py delete mode 100644 nmreval/gui_qt/fit/function_creation_dialog.py delete mode 100644 nmreval/math/wideline.py delete mode 100644 nmreval/models/gengamma.py delete mode 100644 resources/_ui/fitcreationdialog.ui rename {nmreval => src}/gui_qt/Qt.py (81%) rename {nmreval => src}/gui_qt/__init__.py (89%) rename {nmreval => src}/gui_qt/_py/__init__.py (100%) rename {nmreval => src}/gui_qt/_py/agroptiondialog.py (100%) rename {nmreval => src}/gui_qt/_py/apod_dialog.py (100%) rename {nmreval => src}/gui_qt/_py/asciidialog.py (100%) rename {nmreval => src}/gui_qt/_py/axisConfigTemplate.py (100%) rename {nmreval => src}/gui_qt/_py/baseline_dialog.py (100%) rename {nmreval => src}/gui_qt/_py/basewindow.py (100%) rename {nmreval => src}/gui_qt/_py/bdsdialog.py (100%) rename {nmreval => src}/gui_qt/_py/color_palette.py (100%) rename {nmreval => src}/gui_qt/_py/coupling_calculator.py (100%) rename {nmreval => src}/gui_qt/_py/coupling_t1_from_tau.py (100%) rename {nmreval => src}/gui_qt/_py/datawidget.py (100%) rename {nmreval => src}/gui_qt/_py/dscfile_dialog.py (100%) rename {nmreval => src}/gui_qt/_py/editsignalwidget.py (100%) rename {nmreval => src}/gui_qt/_py/eval_expr_dialog.py (100%) rename {nmreval => src}/gui_qt/_py/evalexpression.py (100%) rename {nmreval => src}/gui_qt/_py/expandablewidget.py (100%) rename {nmreval => src}/gui_qt/_py/exportConfigTemplate.py (100%) rename {nmreval => src}/gui_qt/_py/fcreader.py (100%) rename {nmreval => src}/gui_qt/_py/filedialog.py (100%) create mode 100644 src/gui_qt/_py/fitcreationdialog.py rename {nmreval => src}/gui_qt/_py/fitdialog.py (100%) rename {nmreval => src}/gui_qt/_py/fitdialog_window.py (100%) rename {nmreval => src}/gui_qt/_py/fitfunctionwidget.py (100%) rename {nmreval => src}/gui_qt/_py/fitfuncwidget.py (100%) rename {nmreval => src}/gui_qt/_py/fitfuncwidget_old.py (100%) rename {nmreval => src}/gui_qt/_py/fitmodelfixwidget.py (100%) rename {nmreval => src}/gui_qt/_py/fitmodelwidget.py (100%) rename {nmreval => src}/gui_qt/_py/fitparametertable.py (100%) rename {nmreval => src}/gui_qt/_py/fitparameterwidget.py (100%) rename {nmreval => src}/gui_qt/_py/fitresult.py (100%) rename {nmreval => src}/gui_qt/_py/ftdialog.py (100%) rename {nmreval => src}/gui_qt/_py/function_tree_widget.py (100%) rename {nmreval => src}/gui_qt/_py/gol.py (100%) rename {nmreval => src}/gui_qt/_py/gracemsgdialog.py (100%) rename {nmreval => src}/gui_qt/_py/gracereader.py (100%) rename {nmreval => src}/gui_qt/_py/graph.py (100%) rename {nmreval => src}/gui_qt/_py/guidelinewidget.py (100%) rename {nmreval => src}/gui_qt/_py/hdftree.py (100%) rename {nmreval => src}/gui_qt/_py/integral_widget.py (100%) rename {nmreval => src}/gui_qt/_py/integratederive_dialog.py (100%) rename {nmreval => src}/gui_qt/_py/interpol_dialog.py (100%) rename {nmreval => src}/gui_qt/_py/lineedit_dialog.py (100%) rename {nmreval => src}/gui_qt/_py/mean_form.py (100%) rename {nmreval => src}/gui_qt/_py/meandialog.py (100%) rename {nmreval => src}/gui_qt/_py/modelwidget.py (100%) rename {nmreval => src}/gui_qt/_py/move_dialog.py (100%) rename {nmreval => src}/gui_qt/_py/namespace_widget.py (100%) rename {nmreval => src}/gui_qt/_py/option_selection.py (100%) rename {nmreval => src}/gui_qt/_py/parameterform.py (100%) rename {nmreval => src}/gui_qt/_py/phase_corr_dialog.py (100%) rename {nmreval => src}/gui_qt/_py/plotConfigTemplate.py (100%) rename {nmreval => src}/gui_qt/_py/pokemon.py (100%) rename {nmreval => src}/gui_qt/_py/propwidget.py (100%) rename {nmreval => src}/gui_qt/_py/ptstab.py (100%) rename {nmreval => src}/gui_qt/_py/qfiledialog.py (100%) rename {nmreval => src}/gui_qt/_py/save_fit_parameter.py (100%) rename {nmreval => src}/gui_qt/_py/save_fitmodel_dialog.py (100%) rename {nmreval => src}/gui_qt/_py/save_options.py (100%) rename {nmreval => src}/gui_qt/_py/saveoptions.py (100%) rename {nmreval => src}/gui_qt/_py/sdmodelwidget.py (100%) rename {nmreval => src}/gui_qt/_py/selection_widget.py (100%) rename {nmreval => src}/gui_qt/_py/setbyfunction_dialog.py (100%) rename {nmreval => src}/gui_qt/_py/shift_scale_dialog.py (99%) rename {nmreval => src}/gui_qt/_py/skipdialog.py (100%) rename {nmreval => src}/gui_qt/_py/smoothdialog.py (100%) rename {nmreval => src}/gui_qt/_py/t1_calc_dialog.py (100%) rename {nmreval => src}/gui_qt/_py/t1_dock.py (100%) rename {nmreval => src}/gui_qt/_py/t1_tau_calculation.py (100%) rename {nmreval => src}/gui_qt/_py/t1dialog.py (100%) rename {nmreval => src}/gui_qt/_py/tntdialog.py (100%) rename {nmreval => src}/gui_qt/_py/typeconversion.py (100%) rename {nmreval => src}/gui_qt/_py/untitled.py (100%) rename {nmreval => src}/gui_qt/_py/userfitassist.py (100%) rename {nmreval => src}/gui_qt/_py/usermodeleditor.py (100%) rename {nmreval => src}/gui_qt/_py/valueeditor.py (100%) rename {nmreval => src}/gui_qt/data/__init__.py (100%) rename {nmreval => src}/gui_qt/data/container.py (98%) rename {nmreval => src}/gui_qt/data/conversion.py (100%) rename {nmreval => src}/gui_qt/data/datawidget/__init__.py (100%) rename {nmreval => src}/gui_qt/data/datawidget/datawidget.py (99%) rename {nmreval => src}/gui_qt/data/datawidget/properties.py (100%) rename {nmreval => src}/gui_qt/data/integral_widget.py (100%) rename {nmreval => src}/gui_qt/data/interpolate_dialog.py (100%) rename {nmreval => src}/gui_qt/data/plot_dialog.py (96%) rename {nmreval => src}/gui_qt/data/point_select.py (100%) rename {nmreval => src}/gui_qt/data/shift_graphs.py (99%) rename {nmreval => src}/gui_qt/data/signaledit/__init__.py (100%) rename {nmreval => src}/gui_qt/data/signaledit/baseline_dialog.py (94%) rename {nmreval => src}/gui_qt/data/signaledit/editsignalwidget.py (96%) rename {nmreval => src}/gui_qt/data/signaledit/phase_dialog.py (95%) rename {nmreval => src}/gui_qt/data/valueeditwidget.py (99%) rename {nmreval => src}/gui_qt/fit/__init__.py (100%) rename {nmreval => src}/gui_qt/fit/fit_forms.py (98%) rename {nmreval => src}/gui_qt/fit/fit_parameter.py (99%) rename {nmreval => src}/gui_qt/fit/fitfunction.py (94%) rename {nmreval => src}/gui_qt/fit/fitwindow.py (99%) create mode 100644 src/gui_qt/fit/function_creation_dialog.py rename {nmreval => src}/gui_qt/fit/result.py (99%) rename {nmreval => src}/gui_qt/graphs/__init__.py (100%) rename {nmreval => src}/gui_qt/graphs/graphwindow.py (99%) rename {nmreval => src}/gui_qt/graphs/guide_lines.py (100%) rename {nmreval => src}/gui_qt/graphs/movedialog.py (100%) rename {nmreval => src}/gui_qt/io/__init__.py (100%) rename {nmreval => src}/gui_qt/io/asciireader.py (99%) rename {nmreval => src}/gui_qt/io/bdsreader.py (98%) rename {nmreval => src}/gui_qt/io/dscreader.py (98%) rename {nmreval => src}/gui_qt/io/exporters.py (97%) rename {nmreval => src}/gui_qt/io/fcbatchreader.py (96%) rename {nmreval => src}/gui_qt/io/filedialog.py (100%) rename {nmreval => src}/gui_qt/io/filereaders.py (95%) rename {nmreval => src}/gui_qt/io/gracereader.py (95%) rename {nmreval => src}/gui_qt/io/hdfreader.py (99%) rename {nmreval => src}/gui_qt/io/nmrreader.py (95%) rename {nmreval => src}/gui_qt/io/save_fitparameter.py (100%) rename {nmreval => src}/gui_qt/io/tntreader.py (98%) rename {nmreval => src}/gui_qt/lib/__init__.py (100%) rename {nmreval => src}/gui_qt/lib/codeeditor.py (100%) rename {nmreval => src}/gui_qt/lib/color_dialog.py (96%) rename {nmreval => src}/gui_qt/lib/configurations.py (98%) rename {nmreval => src}/gui_qt/lib/decorators.py (100%) rename {nmreval => src}/gui_qt/lib/delegates.py (98%) rename {nmreval => src}/gui_qt/lib/expandablewidget.py (100%) rename {nmreval => src}/gui_qt/lib/forms.py (99%) rename {nmreval => src}/gui_qt/lib/gol.py (100%) rename {nmreval => src}/gui_qt/lib/namespace.py (97%) rename {nmreval => src}/gui_qt/lib/pg_objects.py (98%) rename {nmreval => src}/gui_qt/lib/randpok.py (100%) rename {nmreval => src}/gui_qt/lib/spinboxes.py (100%) rename {nmreval => src}/gui_qt/lib/stuff.py (100%) rename {nmreval => src}/gui_qt/lib/styles.py (100%) rename {nmreval => src}/gui_qt/lib/tables.py (100%) rename {nmreval => src}/gui_qt/lib/undos.py (100%) rename {nmreval => src}/gui_qt/lib/usermodeleditor.py (100%) rename {nmreval => src}/gui_qt/lib/utils.py (100%) rename {nmreval => src}/gui_qt/main/__init__.py (100%) rename {nmreval => src}/gui_qt/main/mainwindow.py (99%) rename {nmreval => src}/gui_qt/main/management.py (98%) rename {nmreval/io => src/gui_qt/math}/__init__.py (100%) rename {nmreval => src}/gui_qt/math/bootstrap.py (100%) rename {nmreval => src}/gui_qt/math/evaluation.py (98%) rename {nmreval => src}/gui_qt/math/integrate_derive.py (100%) rename {nmreval => src}/gui_qt/math/interpol.py (100%) rename {nmreval => src}/gui_qt/math/mean_dialog.py (97%) rename {nmreval => src}/gui_qt/math/skipping.py (100%) rename {nmreval => src}/gui_qt/math/smooth.py (100%) rename {nmreval/lib => src/gui_qt/nmr}/__init__.py (100%) rename {nmreval => src}/gui_qt/nmr/coupling_calc.py (96%) rename {nmreval => src}/gui_qt/nmr/t1_from_tau.py (96%) rename {nmreval => src}/gui_qt/nmr/t1widget.py (98%) rename {nmreval => src/nmreval}/__init__.py (100%) rename {nmreval => src/nmreval}/bds/__init__.py (100%) rename {nmreval => src/nmreval}/configs.py (100%) rename {nmreval => src/nmreval}/data/__init__.py (100%) rename {nmreval => src/nmreval}/data/bds.py (100%) rename {nmreval => src/nmreval}/data/dsc.py (100%) rename {nmreval => src/nmreval}/data/nmr.py (99%) rename {nmreval => src/nmreval}/data/points.py (94%) rename {nmreval => src/nmreval}/data/signals.py (96%) rename {nmreval => src/nmreval}/distributions/__init__.py (93%) rename {nmreval => src/nmreval}/distributions/base.py (95%) rename {nmreval => src/nmreval}/distributions/colecole.py (59%) rename {nmreval => src/nmreval}/distributions/coledavidson.py (93%) rename {nmreval => src/nmreval}/distributions/debye.py (89%) rename {nmreval => src/nmreval}/distributions/energy.py (66%) create mode 100644 src/nmreval/distributions/gengamma.py rename {nmreval => src/nmreval}/distributions/havriliaknegami.py (88%) rename {nmreval => src/nmreval}/distributions/intermolecular.py (100%) rename {nmreval => src/nmreval}/distributions/kww.py (100%) rename {nmreval => src/nmreval}/distributions/loggaussian.py (98%) rename {nmreval/math => src/nmreval/dsc}/__init__.py (100%) rename {nmreval => src/nmreval}/dsc/calibration.py (99%) rename {nmreval => src/nmreval}/dsc/dsc_calibration_fast_neu.py (100%) rename {nmreval => src/nmreval}/fit/__init__.py (100%) rename {nmreval => src/nmreval}/fit/_meta.py (97%) rename {nmreval => src/nmreval}/fit/data.py (100%) rename {nmreval => src/nmreval}/fit/minimizer.py (100%) rename {nmreval => src/nmreval}/fit/model.py (100%) rename {nmreval => src/nmreval}/fit/parameter.py (100%) rename {nmreval => src/nmreval}/fit/result.py (100%) rename {resources => src/nmreval/io}/__init__.py (100%) rename {nmreval => src/nmreval}/io/asciireader.py (100%) rename {nmreval => src/nmreval}/io/bds_reader.py (99%) rename {nmreval => src/nmreval}/io/dsc.py (99%) rename {nmreval => src/nmreval}/io/fcbatchreader.py (77%) rename {nmreval => src/nmreval}/io/graceeditor.py (99%) rename {nmreval => src/nmreval}/io/hdfreader.py (99%) rename {nmreval => src/nmreval}/io/merge_agr.py (99%) rename {nmreval => src/nmreval}/io/nmrreader.py (96%) rename {nmreval => src/nmreval}/io/read_old_nmr.py (100%) rename {nmreval => src/nmreval}/io/sessionwriter.py (100%) rename {nmreval => src/nmreval}/io/tntreader.py (100%) rename {resources/icons => src/nmreval/lib}/__init__.py (100%) rename {nmreval => src/nmreval}/lib/colors.py (100%) rename {nmreval => src/nmreval}/lib/decorator.py (100%) rename {nmreval => src/nmreval}/lib/importer.py (92%) rename {nmreval => src/nmreval}/lib/lines.py (100%) rename {nmreval => src/nmreval}/lib/logger.py (100%) rename {nmreval => src/nmreval}/lib/symbols.py (98%) rename {nmreval => src/nmreval}/lib/utils.py (100%) create mode 100644 src/nmreval/math/__init__.py rename {nmreval => src/nmreval}/math/apodization.py (78%) rename {nmreval => src/nmreval}/math/interpol.py (100%) rename {nmreval => src/nmreval}/math/kww.py (100%) rename {nmreval => src/nmreval}/math/logfourier.py (100%) rename {nmreval => src/nmreval}/math/mittagleffler.py (98%) rename {nmreval => src/nmreval}/math/orientations.py (100%) rename {nmreval => src/nmreval}/math/pca.py (100%) rename {nmreval => src/nmreval}/math/smooth.py (100%) rename {nmreval => src/nmreval}/models/__init__.py (100%) rename {nmreval => src/nmreval}/models/basic.py (100%) rename {nmreval => src/nmreval}/models/bds.py (100%) rename {nmreval => src/nmreval}/models/correlationfuncs.py (100%) rename {nmreval => src/nmreval}/models/diffusion.py (100%) rename {nmreval => src/nmreval}/models/fieldcycling.py (100%) rename {nmreval => src/nmreval}/models/relaxation.py (100%) rename {nmreval => src/nmreval}/models/spectrum.py (97%) rename {nmreval => src/nmreval}/models/stimecho.py (100%) rename {nmreval => src/nmreval}/models/temperature.py (94%) rename {nmreval => src/nmreval}/models/transitions.py (100%) rename {nmreval => src/nmreval}/models/usermodels.py (100%) rename {nmreval => src/nmreval}/models/wideline.py (100%) rename {nmreval => src/nmreval}/nmr/__init__.py (100%) rename {nmreval => src/nmreval}/nmr/coupling.py (100%) rename {nmreval => src/nmreval}/nmr/fc_eval.py (100%) rename {nmreval => src/nmreval}/nmr/relaxation.py (99%) rename {nmreval => src/nmreval}/utils/__init__.py (100%) rename {nmreval => src/nmreval}/utils/constants.py (100%) rename {nmreval => src/nmreval}/utils/exception.py (100%) rename {nmreval => src/nmreval}/utils/pca_demo_pcs.py (100%) rename {nmreval => src/nmreval}/utils/pokemon.json (100%) rename {nmreval => src/nmreval}/utils/text.py (100%) rename {nmreval => src/nmreval}/utils/utils.py (100%) rename {nmreval => src/nmreval}/version.py (100%) rename {resources => src/resources}/Default.agr (100%) rename {resources/nmr => src/resources}/__init__.py (100%) rename {resources => src/resources}/_rc/axes.png (100%) rename {resources => src/resources}/_rc/blackwhite.png (100%) rename {resources => src/resources}/_rc/blackwhite.svg (100%) rename {resources => src/resources}/_rc/cat.png (100%) rename {resources => src/resources}/_rc/colors.png (100%) rename {resources => src/resources}/_rc/colors.svg (100%) rename {resources => src/resources}/_rc/cut_region.png (100%) rename {resources => src/resources}/_rc/eval_button.png (100%) rename {resources => src/resources}/_rc/fit_preview.png (100%) rename {resources => src/resources}/_rc/fit_region.png (100%) rename {resources => src/resources}/_rc/grid.png (100%) rename {resources => src/resources}/_rc/grid.svg (100%) rename {resources => src/resources}/_rc/imag.png (100%) rename {resources => src/resources}/_rc/imag.svg (100%) rename {resources => src/resources}/_rc/images.qrc (100%) rename {resources => src/resources}/_rc/left.png (100%) rename {resources => src/resources}/_rc/logo.png (100%) rename {resources => src/resources}/_rc/mean.png (100%) rename {resources => src/resources}/_rc/mouse.png (100%) rename {resources => src/resources}/_rc/open_session.png (100%) rename {resources => src/resources}/_rc/path48-3-5-6-2.png (100%) rename {resources => src/resources}/_rc/properties.png (100%) rename {resources => src/resources}/_rc/punktdings.png (100%) rename {resources => src/resources}/_rc/real.png (100%) rename {resources => src/resources}/_rc/real.svg (100%) rename {resources => src/resources}/_rc/right.png (100%) rename {resources => src/resources}/_rc/sort.png (100%) rename {resources => src/resources}/_rc/xlog.png (100%) rename {resources => src/resources}/_rc/xlog.svg (100%) rename {resources => src/resources}/_rc/ylog.png (100%) rename {resources => src/resources}/_rc/ylog.svg (100%) rename {resources => src/resources}/_ui/agroptiondialog.ui (100%) rename {resources => src/resources}/_ui/apod_dialog.ui (100%) rename {resources => src/resources}/_ui/asciidialog.ui (100%) rename {resources => src/resources}/_ui/axisConfigTemplate.ui (100%) rename {resources => src/resources}/_ui/baseline_dialog.ui (100%) rename {resources => src/resources}/_ui/basewindow.ui (100%) rename {resources => src/resources}/_ui/bdsdialog.ui (100%) rename {resources => src/resources}/_ui/color_palette.ui (100%) rename {resources => src/resources}/_ui/coupling_calculator.ui (100%) rename {resources => src/resources}/_ui/coupling_t1_from_tau.ui (100%) rename {resources => src/resources}/_ui/datawidget.ui (100%) rename {resources => src/resources}/_ui/dscfile_dialog.ui (100%) rename {resources => src/resources}/_ui/editsignalwidget.ui (100%) rename {resources => src/resources}/_ui/eval_expr_dialog.ui (100%) rename {resources => src/resources}/_ui/evalexpression.ui (100%) rename {resources => src/resources}/_ui/expandablewidget.ui (100%) rename {resources => src/resources}/_ui/exportConfigTemplate.ui (100%) rename {resources => src/resources}/_ui/fcreader.ui (100%) rename {resources => src/resources}/_ui/filedialog.ui (100%) create mode 100644 src/resources/_ui/fitcreationdialog.ui rename {resources => src/resources}/_ui/fitdialog.ui (100%) rename {resources => src/resources}/_ui/fitdialog_window.ui (100%) rename {resources => src/resources}/_ui/fitfunctionwidget.ui (100%) rename {resources => src/resources}/_ui/fitfuncwidget.ui (100%) rename {resources => src/resources}/_ui/fitfuncwidget_old.ui (100%) rename {resources => src/resources}/_ui/fitmodelfixwidget.ui (100%) rename {resources => src/resources}/_ui/fitmodelwidget.ui (100%) rename {resources => src/resources}/_ui/fitparametertable.ui (100%) rename {resources => src/resources}/_ui/fitparameterwidget.ui (100%) rename {resources => src/resources}/_ui/fitresult.ui (100%) rename {resources => src/resources}/_ui/ftdialog.ui (100%) rename {resources => src/resources}/_ui/function_tree_widget.ui (100%) rename {resources => src/resources}/_ui/gol.ui (100%) rename {resources => src/resources}/_ui/gracemsgdialog.ui (100%) rename {resources => src/resources}/_ui/gracereader.ui (100%) rename {resources => src/resources}/_ui/graph.ui (100%) rename {resources => src/resources}/_ui/guidelinewidget.ui (100%) rename {resources => src/resources}/_ui/hdftree.ui (100%) rename {resources => src/resources}/_ui/integral_widget.ui (100%) rename {resources => src/resources}/_ui/integratederive_dialog.ui (100%) rename {resources => src/resources}/_ui/interpol_dialog.ui (100%) rename {resources => src/resources}/_ui/lineedit_dialog.ui (100%) rename {resources => src/resources}/_ui/mean_form.ui (100%) rename {resources => src/resources}/_ui/meandialog.ui (100%) rename {resources => src/resources}/_ui/modelwidget.ui (100%) rename {resources => src/resources}/_ui/move_dialog.ui (100%) rename {resources => src/resources}/_ui/namespace_widget.ui (100%) rename {resources => src/resources}/_ui/option_selection.ui (100%) rename {resources => src/resources}/_ui/parameterform.ui (100%) rename {resources => src/resources}/_ui/phase_corr_dialog.ui (100%) rename {resources => src/resources}/_ui/plotConfigTemplate.ui (100%) rename {resources => src/resources}/_ui/pokemon.ui (100%) rename {resources => src/resources}/_ui/propwidget.ui (100%) rename {resources => src/resources}/_ui/ptstab.ui (100%) rename {resources => src/resources}/_ui/qfiledialog.ui (100%) rename {resources => src/resources}/_ui/save_fit_parameter.ui (100%) rename {resources => src/resources}/_ui/save_fitmodel_dialog.ui (100%) rename {resources => src/resources}/_ui/save_options.ui (100%) rename {resources => src/resources}/_ui/saveoptions.ui (100%) rename {resources => src/resources}/_ui/sdmodelwidget.ui (100%) rename {resources => src/resources}/_ui/selection_widget.ui (100%) rename {resources => src/resources}/_ui/setbyfunction_dialog.ui (100%) rename {resources => src/resources}/_ui/shift_scale_dialog.ui (99%) rename {resources => src/resources}/_ui/skipdialog.ui (100%) rename {resources => src/resources}/_ui/smoothdialog.ui (100%) rename {resources => src/resources}/_ui/t1_calc_dialog.ui (100%) rename {resources => src/resources}/_ui/t1_dock.ui (100%) rename {resources => src/resources}/_ui/t1_tau_calculation.ui (100%) rename {resources => src/resources}/_ui/t1dialog.ui (100%) rename {resources => src/resources}/_ui/tntdialog.ui (100%) rename {resources => src/resources}/_ui/typeconversion.ui (100%) rename {resources => src/resources}/_ui/untitled.ui (100%) rename {resources => src/resources}/_ui/userfitassist.ui (100%) rename {resources => src/resources}/_ui/usermodeleditor.ui (100%) rename {resources => src/resources}/_ui/valueeditor.ui (100%) create mode 100644 src/resources/icons/__init__.py rename {resources => src/resources}/icons/icons.json (100%) rename {resources => src/resources}/icons/logo.png (100%) rename {resources => src/resources}/icons/normal_light/__init__.py (100%) rename {resources => src/resources}/icons/normal_light/blackwhite.png (100%) rename {resources => src/resources}/icons/normal_light/colors.png (100%) rename {resources => src/resources}/icons/normal_light/concat.png (100%) rename {resources => src/resources}/icons/normal_light/errors.png (100%) rename {resources => src/resources}/icons/normal_light/eval_expression.png (100%) rename {resources => src/resources}/icons/normal_light/fit.png (100%) rename {resources => src/resources}/icons/normal_light/fit_region.png (100%) rename {resources => src/resources}/icons/normal_light/geteilt_icon.png (100%) rename {resources => src/resources}/icons/normal_light/grid.png (100%) rename {resources => src/resources}/icons/normal_light/imag.png (100%) rename {resources => src/resources}/icons/normal_light/left.png (100%) rename {resources => src/resources}/icons/normal_light/legend.png (100%) rename {resources => src/resources}/icons/normal_light/mal_icon.png (100%) rename {resources => src/resources}/icons/normal_light/mean.png (100%) rename {resources => src/resources}/icons/normal_light/messdings.png (100%) rename {resources => src/resources}/icons/normal_light/minus_icon.png (100%) rename {resources => src/resources}/icons/normal_light/mouse.png (100%) rename {resources => src/resources}/icons/normal_light/new.png (100%) rename {resources => src/resources}/icons/normal_light/normal.png (100%) rename {resources => src/resources}/icons/normal_light/open.png (100%) rename {resources => src/resources}/icons/normal_light/plus.png (100%) rename {resources => src/resources}/icons/normal_light/plus_icon.png (100%) rename {resources => src/resources}/icons/normal_light/points_pick.png (100%) rename {resources => src/resources}/icons/normal_light/real.png (100%) rename {resources => src/resources}/icons/normal_light/right.png (100%) rename {resources => src/resources}/icons/normal_light/save.png (100%) rename {resources => src/resources}/icons/normal_light/save_session.png (100%) rename {resources => src/resources}/icons/normal_light/scaling.png (100%) rename {resources => src/resources}/icons/normal_light/sort.png (100%) rename {resources => src/resources}/icons/normal_light/t1_from_tau.png (100%) rename {resources => src/resources}/icons/normal_light/tau_from_t1.png (100%) rename {resources => src/resources}/icons/normal_light/values.png (100%) rename {resources => src/resources}/icons/normal_light/xlog.png (100%) rename {resources => src/resources}/icons/normal_light/ylog.png (100%) rename {resources => src/resources}/icons/pokemon_light/__init__.py (100%) rename {resources => src/resources}/icons/pokemon_light/blackwhite.png (100%) rename {resources => src/resources}/icons/pokemon_light/colors.png (100%) rename {resources => src/resources}/icons/pokemon_light/concat.png (100%) rename {resources => src/resources}/icons/pokemon_light/errors.png (100%) rename {resources => src/resources}/icons/pokemon_light/eval_expression.png (100%) rename {resources => src/resources}/icons/pokemon_light/fit.png (100%) rename {resources => src/resources}/icons/pokemon_light/fit_region.png (100%) rename {resources => src/resources}/icons/pokemon_light/geteilt_icon.png (100%) rename {resources => src/resources}/icons/pokemon_light/grid.png (100%) rename {resources => src/resources}/icons/pokemon_light/imag.png (100%) rename {resources => src/resources}/icons/pokemon_light/left.png (100%) rename {resources => src/resources}/icons/pokemon_light/legend.png (100%) rename {resources => src/resources}/icons/pokemon_light/mal_icon.png (100%) rename {resources => src/resources}/icons/pokemon_light/mean.png (100%) rename {resources => src/resources}/icons/pokemon_light/messdings.png (100%) rename {resources => src/resources}/icons/pokemon_light/minus_icon.png (100%) rename {resources => src/resources}/icons/pokemon_light/mouse.png (100%) rename {resources => src/resources}/icons/pokemon_light/new.png (100%) rename {resources => src/resources}/icons/pokemon_light/normal.png (100%) rename {resources => src/resources}/icons/pokemon_light/open.png (100%) rename {resources => src/resources}/icons/pokemon_light/plus.png (100%) rename {resources => src/resources}/icons/pokemon_light/plus_icon.png (100%) rename {resources => src/resources}/icons/pokemon_light/points_pick.png (100%) rename {resources => src/resources}/icons/pokemon_light/real.png (100%) rename {resources => src/resources}/icons/pokemon_light/right.png (100%) rename {resources => src/resources}/icons/pokemon_light/save.png (100%) rename {resources => src/resources}/icons/pokemon_light/save_session.png (100%) rename {resources => src/resources}/icons/pokemon_light/scaling.png (100%) rename {resources => src/resources}/icons/pokemon_light/sort.png (100%) rename {resources => src/resources}/icons/pokemon_light/t1_from_tau.png (100%) rename {resources => src/resources}/icons/pokemon_light/tau_from_t1.png (100%) rename {resources => src/resources}/icons/pokemon_light/values.png (100%) rename {resources => src/resources}/icons/pokemon_light/xlog.png (100%) rename {resources => src/resources}/icons/pokemon_light/ylog.png (100%) rename {resources => src/resources}/icons/style.qss (100%) rename {resources => src/resources}/logo.png (100%) rename {resources => src/resources}/nmr/Cole-Cole_min.dat (100%) rename {resources => src/resources}/nmr/Cole-Davidson_min.dat (100%) rename {resources => src/resources}/nmr/KWW_min.dat (100%) rename {resources => src/resources}/nmr/Log-Gaussian_min.dat (100%) rename {resources => src/resources}/nmr/T1_min.npz (100%) create mode 100644 src/resources/nmr/__init__.py diff --git a/bin/evaluate.py b/bin/evaluate.py index f5fc10a..a8a919e 100755 --- a/bin/evaluate.py +++ b/bin/evaluate.py @@ -2,7 +2,7 @@ import sys import pathlib -sys.path.append(str(pathlib.Path().cwd().parent)) +sys.path.append(str(pathlib.Path(__file__).parent.parent / 'src')) from nmreval.configs import check_for_config @@ -15,8 +15,8 @@ check_for_config() from nmreval.lib.logger import handle_exception sys.excepthook = handle_exception -from nmreval.gui_qt import App -from nmreval.gui_qt.main.mainwindow import NMRMainWindow +from gui_qt import App +from gui_qt.main.mainwindow import NMRMainWindow app = App([]) diff --git a/doc/Makefile b/doc/Makefile index 407565f..d471d93 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -4,7 +4,7 @@ # You can set these variables from the command line, and also # from the environment for the first two. SPHINXOPTS ?= -SPHINXBUILD ?= /autohome/dominik/miniconda3/bin/sphinx-build +SPHINXBUILD ?= # /autohome/dominik/miniconda3/bin/sphinx-build SOURCEDIR = /autohome/dominik/nmreval/doc/source BUILDDIR = /autohome/dominik/nmreval/doc/_build diff --git a/doc/examples/nmr/plot_RelaxationEvaluation.py b/doc/examples/nmr/plot_RelaxationEvaluation.py index d9252d8..2a182f9 100644 --- a/doc/examples/nmr/plot_RelaxationEvaluation.py +++ b/doc/examples/nmr/plot_RelaxationEvaluation.py @@ -1,16 +1,9 @@ """ -========== -T1 minimum -========== +================================ +Example of apodization functions +================================ -``RelaxationEvaluation`` is used to get width parameter from a T1 minimum. -As a subclass of ``Relaxation`` it can also be used to calculate Relaxation times. -The basic steps are: - -* Determine a T1 minimum with `nmreval.nmr.RelaxationEvaluation.calculate_t1_min` -* Calculate width parameter of a spectral density/coupling constants/... with - ``RelaxationEvaluation.get_increase`` -* Calculate correlation times from these values with ``RelaxationEvaluation.correlation_from_t1`` +This file """ import numpy as np import matplotlib.pyplot as plt diff --git a/doc/source/_static/fit_dialog.png b/doc/source/_static/fit_dialog.png deleted file mode 100644 index 559aa1420a4e60d187d74a2d0215363e9e758d98..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47372 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

(%#}_CbC%X7YHG-Ft8Se4 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 diff --git a/doc/source/_templates/autosummary/class.rst b/doc/source/_templates/autosummary/class.rst index 4eca388..3584823 100644 --- a/doc/source/_templates/autosummary/class.rst +++ b/doc/source/_templates/autosummary/class.rst @@ -3,25 +3,36 @@ .. currentmodule:: {{ module }} .. autoclass:: {{ objname }} + :exclude-members: {% for item in methods %}{%- if not item.startswith('_') or item in ['__call__'] %}{{ item }}, {% endif %}{%- endfor %} - {% block methods %} - + {%- block methods %} {% if methods %} - .. rubric:: {{ _('Methods') }} - - {% for item in methods %} - .. automethod:: {{ item }} - {%- endfor %} - {% endif %} - {% endblock %} - - {% block attributes %} - {% if attributes %} - .. rubric:: {{ _('Attributes') }} + .. rubric:: Methods .. autosummary:: - {% for item in attributes %} - ~{{ name }}.{{ item }} - {%- endfor %} + :toctree: + + {% for item in methods %} + {%- if not item.startswith('_') or item in ['__call__'] %} ~{{ name }}.{{ item }} {% endif %} - {% endblock %} + {%- endfor %} + {%- endif %} + {%- endblock %} + + {%- block attributes %} + {%- if attributes %} + .. rubric:: Properties + + .. autosummary:: + :toctree: + + {% for item in attributes %} + {%- if not item.startswith('_') or item in ['__call__'] %} ~{{ name }}.{{ item }} + {% endif %} + {%- endfor %} + {%- endif %} + {%- endblock %} + +.. _sphx_glr_backref_{{ fullname }}: +.. minigallery:: {{ objname }} + :add-heading: diff --git a/doc/source/api/distributions.rst b/doc/source/api/distributions.rst index c1489a3..85d4355 100644 --- a/doc/source/api/distributions.rst +++ b/doc/source/api/distributions.rst @@ -1,5 +1,2 @@ .. automodule:: nmreval.distributions :members: - :inherited-members: - :undoc-members: - diff --git a/doc/source/api/index.rst b/doc/source/api/index.rst index 10f0748..000f622 100644 --- a/doc/source/api/index.rst +++ b/doc/source/api/index.rst @@ -11,3 +11,4 @@ Reference models distributions nmr + math diff --git a/doc/source/conf.py b/doc/source/conf.py index 4f0356f..b7a6daa 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -12,7 +12,7 @@ # import os import sys -sys.path.append('/autohome/dominik/nmreval') +sys.path.append(os.path.abspath('../../src')) import nmreval @@ -43,6 +43,9 @@ extensions = [ 'sphinx.ext.viewcode', 'sphinx.ext.intersphinx', 'sphinx_gallery.gen_gallery', + 'sphinx.ext.todo', + 'sphinx.ext.autosectionlabel', + 'sphinx.ext.mathjax', ] # configuration for intersphinx @@ -56,7 +59,7 @@ intersphinx_mapping = { # # autodoc options autodoc_typehints = 'none' -autodoc_class_signature = 'separated' +# autodoc_class_signature = 'separated' autoclass_content = 'class' autodoc_member_order = 'groupwise' # @@ -79,6 +82,7 @@ sphinx_gallery_conf = { 'min_reported_time': 10000000000, 'show_memory': False, 'show_signature': False, + 'line_numbers': True, } # The suffix(es) of source filenames. @@ -151,15 +155,23 @@ todo_include_todos = False # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -html_theme = 'pydata_sphinx_theme' +html_theme = 'sphinx_material' # 'sphinx_rtd_theme' # 'pydata_sphinx_theme' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. html_theme_options = { - 'collapse_navigation': False, - 'show_prev_next': False, - 'navbar_end': ['navbar-icon-links.html', 'search-field.html'], + 'nav_title': 'nmreval', + # 'base_url': 'https://chaos3.fkp.physik.tu-darmstadt.de/source/nmreval', + 'repo_url': 'https://chaos3.fkp.physik.tu-darmstadt.de/source/nmreval', + 'repo_name': 'Repo', + 'html_minify': True, + 'css_minify': True, + 'master_doc': False, + 'globaltoc_depth': 3, + 'globaltoc_collapse': True, + 'globaltoc_includehidden': True, + 'heroes': {'index': 'Fun for the whole family!!!!'} } # Add any paths that contain custom themes here, relative to this directory. @@ -183,10 +195,10 @@ html_static_path = ['_static'] html_logo = '_static/logo.png' # Custom sidebar templates, maps document names to template names. -html_sidebars = {'**': ['sidebar-nav-bs.html']} -# html_sidebars = { -# '**': ['localtoc.html', 'relations.html', 'sourcelink.html', 'searchbox.html'], -# } +html_sidebars = { + "**": ["logo-text.html", "globaltoc.html", "localtoc.html", "searchbox.html"] +} + # If true, links to the reST sources are added to the pages. html_show_sourcelink = False @@ -205,7 +217,7 @@ html_last_updated_fmt = '' html_additional_pages = {} # If false, no module index is generated. -html_domain_indices = False +html_domain_indices = True # If false, no index is generated. html_use_index = True @@ -214,10 +226,10 @@ html_use_index = True html_split_index = False # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -# html_show_sphinx = True +html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -# html_show_copyright = True +html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the diff --git a/doc/source/index.rst b/doc/source/index.rst index 6b3d246..8160915 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -10,15 +10,15 @@ NMREval documentation .. toctree:: :maxdepth: 1 + install.rst user_guide/index gallery/index api/index -Indices and tables -================== +Indices +======= -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` +| :ref:`genindex` +| :ref:`modindex` diff --git a/doc/source/nmr/pake.rst b/doc/source/nmr/pake.rst index 1e66f6d..c5ef757 100644 --- a/doc/source/nmr/pake.rst +++ b/doc/source/nmr/pake.rst @@ -11,7 +11,8 @@ In general, time signals are calculated by integration of all orientations (see .. math:: g(t) = \int f[\omega_\text{int}(\theta, \phi)t]\sin\theta\,\mathrm{d}\theta\,\mathrm{d}\phi -with :math:`f(\theta, \phi, t) = \cos[\omega_\text{int}(\theta, \phi) t]` or :math:`\exp[i\omega_\text{int}(\theta) t]` and fourier transform for a spectrum. +with :math:`f(\theta, \phi, t) = \cos[\omega_\text{int}(\theta, \phi) t]` or :math:`\exp[i\omega_\text{int}(\theta) t]` +and fourier transform for a spectrum. However, summation over :math:`\theta`, :math:`\phi`, and calculating :math:`f(\theta, \phi, t)` for each orientation is time consuming. Alternatively, if the orientations are equidistant in :math:`\cos\theta`, one can get to the spectrum directly by creating a histogram of :math:`\omega_\text{int}(\theta, \phi)`, thus circumventing a lot of calculations. diff --git a/doc/source/user_guide/fit.rst b/doc/source/user_guide/fit.rst index 959e836..310873d 100644 --- a/doc/source/user_guide/fit.rst +++ b/doc/source/user_guide/fit.rst @@ -4,10 +4,6 @@ Fitting data ============ -.. image:: ../_static/fit_dialog.png - :scale: 80% - :align: center - The picture gives an example of dialog to setup and start fits. First, there is the possibiity to fit different functions, called models to differentiate from the functions inside each model, to different data simultaneously. diff --git a/doc/source/user_guide/index.rst b/doc/source/user_guide/index.rst index 2ec252f..60ff693 100644 --- a/doc/source/user_guide/index.rst +++ b/doc/source/user_guide/index.rst @@ -1,11 +1,13 @@ -========== +********** User Guide -========== +********** .. toctree:: :maxdepth: 2 - read + gui/index + read/index + edit_signals fit shift_scale diff --git a/doc/source/user_guide/read.rst b/doc/source/user_guide/read.rst deleted file mode 100644 index a423962..0000000 --- a/doc/source/user_guide/read.rst +++ /dev/null @@ -1,19 +0,0 @@ -.. _user_guide.read: - -************* -Reading files -************* - -Supported filetypes are - - * Text files, - * DAMARIS HDF5 files, - * Grace images. - * HP alpha-analyzer EPS files - * NTNMR .tnt files - -DAMARIS HDF files -================= - -After scanning the selected file the program shows a list of the available data. - diff --git a/nmreval/distributions/gengamma.py b/nmreval/distributions/gengamma.py deleted file mode 100644 index 3c96063..0000000 --- a/nmreval/distributions/gengamma.py +++ /dev/null @@ -1,111 +0,0 @@ -from typing import Union - -import numpy as np -from scipy.integrate import simps -from scipy.special import gammaln - -from .base import Distribution - - -class GGAlpha(Distribution): - name = r'General \Gamma (\alpha-process)' - parameter = [r'\alpha', r'\beta'] - - @staticmethod - def correlation(t, tau0, *args): - logtau0 = np.log(tau0) - logtau = np.linspace(logtau0-20, logtau0+20, num=4001) - taus = np.exp(logtau) - gtau = GGAlpha.distribution(taus, tau0, *args) - ret_val = np.array([simps(np.exp(-xvals/taus)*gtau, logtau) for xvals in t]) - return ret_val - - @staticmethod - def susceptibility(omega, tau0, *args): - logtau0 = np.log(tau0) - logtau = np.linspace(logtau0 - 20, logtau0 + 20, num=4001) - taus = np.exp(logtau) - gtau = GGAlpha.distribution(taus, tau0, *args) - ret_val = np.array([simps(1/(1+1j*xvals*taus) * gtau, logtau) for xvals in omega]) - return ret_val - - @staticmethod - def distribution(taus: Union[float, np.ndarray], tau: float, *args) -> Union[float, np.ndarray]: - alpha, beta = args - b_to_a = beta / alpha - norm = np.exp(gammaln(b_to_a) - b_to_a * np.log(b_to_a)) / alpha - t_to_t0 = taus / tau - ret_val = np.exp(-b_to_a * t_to_t0 ** alpha) * t_to_t0 ** beta - - return ret_val / norm - - -class GGAlphaEW(Distribution): - name = r'General \Gamma (\alpha-process + EW)' - parameter = [r'\alpha', r'\beta'] - - @staticmethod - def correlation(t, tau0, *args): - logtau0 = np.log(tau0) - logtau = np.linspace(logtau0-20, logtau0+20, num=4001) - taus = np.exp(logtau) - gtau = GGAlphaEW.distribution(taus, tau0, *args) - # wir integrieren ueber lntau, nicht tau - ret_val = np.array([simps(np.exp(-xvals/taus)*gtau, logtau) for xvals in t]) - return ret_val - - @staticmethod - def susceptibility(omega, tau0, *args): - logtau0 = np.log(tau0) - logtau = np.linspace(logtau0 - 20, logtau0 + 20, num=4001) - taus = np.exp(logtau) - gtau = GGAlphaEW.distribution(taus, tau0, *args) - ret_val = np.array([simps(1/(1+1j*xvals*taus) * gtau, logtau) for xvals in omega]) - return ret_val - - @staticmethod - def distribution(tau: Union[float, np.ndarray], tau0: float, *args) -> Union[float, np.ndarray]: - alpha, beta, sigma, gamma = args - if gamma == beta: - return GGAlpha.distribution(tau, tau0, alpha, beta) - b_to_a = beta / alpha - g_to_a = gamma / alpha - t_to_t0 = tau / tau0 - norm = (np.exp(gammaln(b_to_a)) + sigma**(gamma-beta) * - np.exp(gammaln(g_to_a) + (b_to_a-g_to_a)*np.log(b_to_a))) / np.exp(b_to_a*np.log(b_to_a)) / alpha - - ret_val = np.exp(-b_to_a * t_to_t0**alpha) * t_to_t0**beta * (1 + (t_to_t0*sigma)**(gamma-beta)) - - return ret_val / norm - - -class GGBeta(Distribution): - name = r'General \Gamma (\beta-process)' - parameter = [r'\alpha', r'\beta'] - - @staticmethod - def correlation(t, tau0, *args): - logtau0 = np.log(tau0) - logtau = np.linspace(logtau0-20, logtau0+20, num=4001) - taus = np.exp(logtau) - gtau = GGBeta.distribution(taus, tau0, *args) - # wir integrieren ueber lntau, nicht tau - ret_val = np.array([simps(np.exp(-xvals/taus)*gtau, logtau) for xvals in t]) - return ret_val - - @staticmethod - def susceptibility(omega, tau0, *args): - logtau0 = np.log(tau0) - logtau = np.linspace(logtau0 - 20, logtau0 + 20, num=4001) - taus = np.exp(logtau) - gtau = GGBeta.distribution(taus, tau0, *args) - ret_val = np.array([simps(1/(1+1j*xvals*taus) * gtau, logtau) for xvals in omega]) - return ret_val - - @staticmethod - def distribution(tau: Union[float, np.ndarray], tau0: float, *args) -> Union[float, np.ndarray]: - a, b = args - norm = a * (1+b) * np.sin(np.pi*b/(1+b)) * b**(b/(1+b)) / np.pi - ret_val = b * (tau/tau0)**a + (tau/tau0)**(-a*b) - - return norm / ret_val diff --git a/nmreval/gui_qt/_py/fitcreationdialog.py b/nmreval/gui_qt/_py/fitcreationdialog.py deleted file mode 100644 index f2abd98..0000000 --- a/nmreval/gui_qt/_py/fitcreationdialog.py +++ /dev/null @@ -1,189 +0,0 @@ -# -*- coding: utf-8 -*- - -# Form implementation generated from reading ui file 'resources/_ui/fitcreationdialog.ui' -# -# Created by: PyQt5 UI code generator 5.12.3 -# -# WARNING! All changes made in this file will be lost! - - -from PyQt5 import QtCore, QtGui, QtWidgets - - -class Ui_Dialog(object): - def setupUi(self, Dialog): - Dialog.setObjectName("Dialog") - Dialog.resize(614, 776) - self.verticalLayout_5 = QtWidgets.QVBoxLayout(Dialog) - self.verticalLayout_5.setContentsMargins(3, 3, 3, 3) - self.verticalLayout_5.setSpacing(3) - self.verticalLayout_5.setObjectName("verticalLayout_5") - self.groupBox = QtWidgets.QGroupBox(Dialog) - self.groupBox.setCheckable(True) - self.groupBox.setChecked(False) - self.groupBox.setObjectName("groupBox") - self.verticalLayout_7 = QtWidgets.QVBoxLayout(self.groupBox) - self.verticalLayout_7.setContentsMargins(3, 3, 3, 3) - self.verticalLayout_7.setSpacing(3) - self.verticalLayout_7.setObjectName("verticalLayout_7") - self.widget_2 = QtWidgets.QWidget(self.groupBox) - self.widget_2.setObjectName("widget_2") - self.gridLayout_2 = QtWidgets.QGridLayout(self.widget_2) - self.gridLayout_2.setContentsMargins(0, 0, 0, 0) - self.gridLayout_2.setSpacing(3) - self.gridLayout_2.setObjectName("gridLayout_2") - self.name_lineedit = QtWidgets.QLineEdit(self.widget_2) - self.name_lineedit.setObjectName("name_lineedit") - self.gridLayout_2.addWidget(self.name_lineedit, 0, 1, 1, 1) - self.group_lineedit = QtWidgets.QLineEdit(self.widget_2) - self.group_lineedit.setObjectName("group_lineedit") - self.gridLayout_2.addWidget(self.group_lineedit, 1, 1, 1, 1) - self.group_label = QtWidgets.QLabel(self.widget_2) - self.group_label.setObjectName("group_label") - self.gridLayout_2.addWidget(self.group_label, 1, 0, 1, 1) - self.name_label = QtWidgets.QLabel(self.widget_2) - self.name_label.setObjectName("name_label") - self.gridLayout_2.addWidget(self.name_label, 0, 0, 1, 1) - self.lineEdit = QtWidgets.QLineEdit(self.widget_2) - self.lineEdit.setObjectName("lineEdit") - self.gridLayout_2.addWidget(self.lineEdit, 2, 1, 1, 1) - self.label_2 = QtWidgets.QLabel(self.widget_2) - self.label_2.setObjectName("label_2") - self.gridLayout_2.addWidget(self.label_2, 2, 0, 1, 1) - self.verticalLayout_7.addWidget(self.widget_2) - self.verticalLayout_5.addWidget(self.groupBox) - self.groupBox_2 = QtWidgets.QGroupBox(Dialog) - self.groupBox_2.setCheckable(True) - self.groupBox_2.setChecked(False) - self.groupBox_2.setObjectName("groupBox_2") - self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.groupBox_2) - self.verticalLayout_2.setContentsMargins(3, 3, 3, 3) - self.verticalLayout_2.setSpacing(3) - self.verticalLayout_2.setObjectName("verticalLayout_2") - self.widget_3 = QtWidgets.QWidget(self.groupBox_2) - self.widget_3.setObjectName("widget_3") - self.verticalLayout_8 = QtWidgets.QVBoxLayout(self.widget_3) - self.verticalLayout_8.setContentsMargins(0, 0, 0, 0) - self.verticalLayout_8.setSpacing(3) - self.verticalLayout_8.setObjectName("verticalLayout_8") - self.tableWidget = QtWidgets.QTableWidget(self.widget_3) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.tableWidget.sizePolicy().hasHeightForWidth()) - self.tableWidget.setSizePolicy(sizePolicy) - self.tableWidget.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection) - self.tableWidget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) - self.tableWidget.setColumnCount(4) - self.tableWidget.setObjectName("tableWidget") - self.tableWidget.setRowCount(0) - item = QtWidgets.QTableWidgetItem() - self.tableWidget.setHorizontalHeaderItem(0, item) - item = QtWidgets.QTableWidgetItem() - self.tableWidget.setHorizontalHeaderItem(1, item) - item = QtWidgets.QTableWidgetItem() - self.tableWidget.setHorizontalHeaderItem(2, item) - item = QtWidgets.QTableWidgetItem() - self.tableWidget.setHorizontalHeaderItem(3, item) - self.verticalLayout_8.addWidget(self.tableWidget) - self.parameter_button = QtWidgets.QToolButton(self.widget_3) - self.parameter_button.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.parameter_button.setAutoRaise(False) - self.parameter_button.setArrowType(QtCore.Qt.RightArrow) - self.parameter_button.setObjectName("parameter_button") - self.verticalLayout_8.addWidget(self.parameter_button) - self.verticalLayout_2.addWidget(self.widget_3) - self.verticalLayout_5.addWidget(self.groupBox_2) - self.groupBox_3 = QtWidgets.QGroupBox(Dialog) - self.groupBox_3.setCheckable(True) - self.groupBox_3.setChecked(False) - self.groupBox_3.setObjectName("groupBox_3") - self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.groupBox_3) - self.verticalLayout_3.setContentsMargins(3, 3, 3, 3) - self.verticalLayout_3.setSpacing(3) - self.verticalLayout_3.setObjectName("verticalLayout_3") - self.widget = QtWidgets.QWidget(self.groupBox_3) - self.widget.setObjectName("widget") - self.verticalLayout_6 = QtWidgets.QVBoxLayout(self.widget) - self.verticalLayout_6.setContentsMargins(0, 0, 0, 0) - self.verticalLayout_6.setSpacing(3) - self.verticalLayout_6.setObjectName("verticalLayout_6") - self.use_nuclei = QtWidgets.QCheckBox(self.widget) - self.use_nuclei.setObjectName("use_nuclei") - self.verticalLayout_6.addWidget(self.use_nuclei) - self.tabWidget = QtWidgets.QTabWidget(self.widget) - self.tabWidget.setTabPosition(QtWidgets.QTabWidget.West) - self.tabWidget.setTabsClosable(True) - self.tabWidget.setObjectName("tabWidget") - self.verticalLayout_6.addWidget(self.tabWidget) - self.selection_button = QtWidgets.QToolButton(self.widget) - self.selection_button.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) - self.selection_button.setArrowType(QtCore.Qt.RightArrow) - self.selection_button.setObjectName("selection_button") - self.verticalLayout_6.addWidget(self.selection_button) - self.verticalLayout_3.addWidget(self.widget) - self.verticalLayout_5.addWidget(self.groupBox_3) - self.groupBox_4 = QtWidgets.QGroupBox(Dialog) - self.groupBox_4.setCheckable(True) - self.groupBox_4.setChecked(False) - self.groupBox_4.setObjectName("groupBox_4") - self.verticalLayout = QtWidgets.QVBoxLayout(self.groupBox_4) - self.verticalLayout.setObjectName("verticalLayout") - self.namespace_widget = QNamespaceWidget(self.groupBox_4) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Preferred) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.namespace_widget.sizePolicy().hasHeightForWidth()) - self.namespace_widget.setSizePolicy(sizePolicy) - self.namespace_widget.setObjectName("namespace_widget") - self.verticalLayout.addWidget(self.namespace_widget) - self.verticalLayout_5.addWidget(self.groupBox_4) - self.frame_4 = QtWidgets.QFrame(Dialog) - self.frame_4.setObjectName("frame_4") - self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.frame_4) - self.verticalLayout_4.setContentsMargins(3, 3, 3, 3) - self.verticalLayout_4.setSpacing(3) - self.verticalLayout_4.setObjectName("verticalLayout_4") - self.label = QtWidgets.QLabel(self.frame_4) - self.label.setObjectName("label") - self.verticalLayout_4.addWidget(self.label) - self.plainTextEdit = CodeEditor(self.frame_4) - self.plainTextEdit.setObjectName("plainTextEdit") - self.verticalLayout_4.addWidget(self.plainTextEdit) - self.verticalLayout_5.addWidget(self.frame_4) - self.buttonBox = QtWidgets.QDialogButtonBox(Dialog) - self.buttonBox.setOrientation(QtCore.Qt.Horizontal) - self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok) - self.buttonBox.setObjectName("buttonBox") - self.verticalLayout_5.addWidget(self.buttonBox) - self.name_label.setBuddy(self.name_lineedit) - - self.retranslateUi(Dialog) - self.buttonBox.accepted.connect(Dialog.accept) - self.buttonBox.rejected.connect(Dialog.reject) - QtCore.QMetaObject.connectSlotsByName(Dialog) - - def retranslateUi(self, Dialog): - _translate = QtCore.QCoreApplication.translate - Dialog.setWindowTitle(_translate("Dialog", "Dialog")) - self.groupBox.setTitle(_translate("Dialog", "Description")) - self.group_label.setText(_translate("Dialog", "Group")) - self.name_label.setText(_translate("Dialog", "Name")) - self.label_2.setText(_translate("Dialog", "Equation")) - self.groupBox_2.setTitle(_translate("Dialog", "Variables")) - item = self.tableWidget.horizontalHeaderItem(0) - item.setText(_translate("Dialog", "Variable")) - item = self.tableWidget.horizontalHeaderItem(1) - item.setText(_translate("Dialog", "Name")) - item = self.tableWidget.horizontalHeaderItem(2) - item.setText(_translate("Dialog", "Lower bound")) - item = self.tableWidget.horizontalHeaderItem(3) - item.setText(_translate("Dialog", "Upper bound")) - self.parameter_button.setText(_translate("Dialog", "Add parameter")) - self.groupBox_3.setTitle(_translate("Dialog", "Multiple choice part")) - self.use_nuclei.setText(_translate("Dialog", "Add gyromagnetic ratios")) - self.selection_button.setText(_translate("Dialog", "Add selection")) - self.groupBox_4.setTitle(_translate("Dialog", "Available namespace")) - self.label.setText(_translate("Dialog", "Function y = func(x)")) -from ..lib.codeeditor import CodeEditor -from ..lib.namespace import QNamespaceWidget diff --git a/nmreval/gui_qt/fit/function_creation_dialog.py b/nmreval/gui_qt/fit/function_creation_dialog.py deleted file mode 100644 index 492e8ad..0000000 --- a/nmreval/gui_qt/fit/function_creation_dialog.py +++ /dev/null @@ -1,238 +0,0 @@ -import re - -import numexpr as ne -import numpy as np - -from ..Qt import QtCore, QtWidgets -from .._py.fitcreationdialog import Ui_Dialog - - -_numexpr_funcs = [] -for k, _ in ne.expressions.functions.items(): - pat = k + r'\(' - _numexpr_funcs.append((re.compile(pat), 'np.' + k + '(')) - - -class QUserFitCreator(QtWidgets.QDialog, Ui_Dialog): - classCreated = QtCore.pyqtSignal(object) - - def __init__(self, parent=None): - super().__init__(parent=parent) - self.setupUi(self) - - self.namespace_widget.make_namespace() - - self.tableWidget.itemChanged.connect(self.update_function) - - self.groupBox.toggled.connect(self.change_visibility) - self.groupBox_2.toggled.connect(self.change_visibility) - self.groupBox_3.toggled.connect(self.change_visibility) - self.groupBox_4.toggled.connect(self.change_visibility) - - self.groupBox.setChecked(True) - - def __call__(self, *args, **kwargs): - for w in [self.lineEdit_4, self.lineEdit, self.lineEdit_3, self.lineEdit_2, - self.parameterLineEdit, self.externalParametersLineEdit]: - w.clear() - - def check(self): - self.name = self.name_lineedit.text() - self.group = self.group_lineedit.text() - self.eq = str(self.lineEdit.text()) - self.p = str(self.parameterLineEdit.text()).split() - self.func = str(self.lineEdit_4.text()) - self._func_string = '' - - error = [] - for k, v in [('Name', self.name), ('Group', self.group), ('Parameters', self.p), ('Function', self.func)]: - if not v: - error.append('Empty ' + str(k)) - if self.name: - if self.name[0].isdigit(): - error.append('Name starts with digit') - if self.p: - if set(self.p) & set(self.ext_p): - error.append('Duplicate entries: {}'.format(list(set(self.p) & set(self.ext_p)))) - if self.p and self.func: - p_test = np.ones((len(self.p)+len(self.ext_p))) - _x = np.arange(2) - namespace = {'x': _x} - for i, pp in enumerate(p_test): - namespace[f'p_{i}'] = pp - self._func_string = self.func + '' - self._func_string = self._func_string.replace('[', '_').replace(']', '') - try: - ne.evaluate(self._func_string, local_dict=namespace) - except KeyError: - error.append(f'Incorrect evaluation {self.func}') - - if error: - QtWidgets.QMessageBox().warning(self, 'Invalid entries', '\n'.join(error)) - else: - return True - - def accept(self): - self.confirm() - super().accept() - - def confirm(self): - print(f' name = {self.name_lineedit.text()}') - group_type = self.group_lineedit.text() - if group_type: - print(f' group = "{group_type}"') - else: - print(' group = "User-defined"') - var = [] - for row in range(self.tableWidget.rowCount()): - var.append(self.tableWidget.item(row, 1).text()) - if var: - print(' params = [r"', end='') - print('", r"'.join(var) + '"]') - else: - print(' params = []') - - print('\n@staticmethod') - print(self.label.text()) - import inspect - for k, v in self.namespace_widget.namespace.flatten().items(): - if inspect.isfunction(v): - print(k, inspect.getmodule(v)) - print(k, [cc[1] for cc in inspect.getmembers(v) if cc[0] == '__qualname__']) - else: - print(k, v) - print(self.plainTextEdit.toPlainText()) - - @QtCore.pyqtSlot(name='on_parameter_button_clicked') - def add_variable(self): - self.tableWidget.blockSignals(True) - row = self.tableWidget.rowCount() - self.tableWidget.setRowCount(row+1) - - self.tableWidget.setItem(row, 0, QtWidgets.QTableWidgetItem('p'+str(row))) - self.tableWidget.setItem(row, 1, QtWidgets.QTableWidgetItem('p_{'+str(row)+'}')) - self.tableWidget.setItem(row, 2, QtWidgets.QTableWidgetItem('--')) - self.tableWidget.setItem(row, 3, QtWidgets.QTableWidgetItem('--')) - self.tableWidget.blockSignals(False) - self.update_function(None) - - @QtCore.pyqtSlot(name='on_selection_button_clicked') - def add_choice(self): - cnt = self.tabWidget.count() - self.tabWidget.addTab(ChoiceWidget(self), 'choice' + str(cnt)) - self.tabWidget.setCurrentIndex(cnt) - - def register(self): - i = 0 - basename = self.name.replace(' ', '') - classname = basename - # while classname in _userfits: - # classname = basename + '_' + str(i) - # i += 1 - c = register_class(classname, self.name, self.group, self.p, self.eq, self._func_string) - self.classCreated.emit(c) - return classname, c - - def save(self, cname): - t = '\n# Created automatically\n' \ - 'class {cname:}(object):\n'\ - ' name = "{name:}"\n' \ - ' type = "{group:}"\n'\ - ' equation = "{eq:}"\n'\ - ' params = {p:}\n' \ - ' ext_params = {ep:}\n\n' \ - ' @staticmethod\n' \ - ' def func(p, x):\n' \ - ' return {func:}\n' - f_string = self.func - for pat, repl in _numexpr_funcs: - f_string = re.sub(pat, repl, f_string) - - @QtCore.pyqtSlot(QtWidgets.QTableWidgetItem) - @QtCore.pyqtSlot(str) - def update_function(self, _): - var = [] - for row in range(self.tableWidget.rowCount()): - var.append(self.tableWidget.item(row, 0).text()) - - if self.use_nuclei.isChecked(): - var.append('nucleus=2.67522128e8') - - # for row in range(self.selection_combobox.count()): - # var.append(self.selection_combobox.itemText(row) + '=') - - self.label.setText('def func(x, ' + ', '.join(var) + '):') - - def change_visibility(self): - sender = self.sender() - - for gb in [self.groupBox, self.groupBox_2, self.groupBox_3, self.groupBox_4]: - gb.blockSignals(True) - gb.setChecked(sender == gb) - gb.blockSignals(False) - - self.widget_2.setVisible(sender == self.groupBox) - self.widget_3.setVisible(sender == self.groupBox_2) - self.widget.setVisible(sender == self.groupBox_3) - self.namespace_widget.setVisible(sender == self.groupBox_4) - - -class ChoiceWidget(QtWidgets.QWidget): - def __init__(self, parent=None): - super().__init__(parent=parent) - - self._init_ui() - - def _init_ui(self): - layout = QtWidgets.QGridLayout() - layout.setContentsMargins(3, 3, 3, 3) - layout.setHorizontalSpacing(6) - - self.label = QtWidgets.QLabel('Name', parent=self) - layout.addWidget(self.label, 0, 0) - self.name_line = QtWidgets.QLineEdit(self) - layout.addWidget(self.name_line, 0, 1) - - self.label_2 = QtWidgets.QLabel('Displayed name', parent=self) - layout.addWidget(self.label_2, 0, 2) - self.display_line = QtWidgets.QLineEdit(self) - layout.addWidget(self.display_line, 0, 3) - - self.label_3 = QtWidgets.QLabel('Type', parent=self) - layout.addWidget(self.label_3) - self.types = QtWidgets.QComboBox(self) - self.types.addItems(['str', 'int', 'float']) - layout.addWidget(self.types) - - self.add_button = QtWidgets.QPushButton('Add option') - layout.addWidget(self.add_button) - - self.table = QtWidgets.QTableWidget(self) - self.table.setColumnCount(2) - self.table.setHorizontalHeaderLabels(['Name', 'Value']) - layout.addWidget(self.table, 2, 0, 1, 4) - - self.setLayout(layout) - - -def register_class(cname, name, group, p, eq, func): - c = type(cname, (), {}) - c.name = name - c.type = group - c.params = p - c.equation = eq - c.func = func_decorator(func) - - return c - - -def func_decorator(f_string): - # we need this decorator because the result is used in a class - - def wrapped_f(*args): - namespace = {'x': args[1]} - for i, pp in enumerate(args[0]): - namespace['p_{}'.format(i)] = pp - return ne.evaluate(f_string, local_dict=namespace) - - return wrapped_f diff --git a/nmreval/math/wideline.py b/nmreval/math/wideline.py deleted file mode 100644 index f996392..0000000 --- a/nmreval/math/wideline.py +++ /dev/null @@ -1,357 +0,0 @@ -import numpy as np -from scipy.integrate import trapz - -from .orientations import zcw_spherical as crystallites - - -class Powder(object): - def __init__(self, n=100): - self.alpha, self.beta, self.wt = crystallites(n) - - -class Pake(object): - parameter = {'delta': 0., 'eta': 0., 'w_iso': 0., - 'x': None, 'y': None, 'half': False} - - def __init__(self, samples=10000): - self.powder = Powder(n=samples) - self.dw = None - self.parameter = {} - self.GB = 1000 - self.pw = 1e-6 - self.legendre = 0 - self.axial = 0 - self.calc_prefactor() - - def calc_prefactor(self): - """ - Calculates angular dependencies - Returns - ------- - - """ - self.legendre = 3 * np.square(np.cos(self.powder.beta)) - 1 - self.axial = np.square(np.sin(self.powder.beta)) * np.cos(2 * self.powder.alpha) - - def set_parameter(self, p, dw=None): - self.parameter['delta'] = p[0] * 1e3 - self.parameter['eta'] = p[1] - self.GB = p[2] * 1e3 - self.pw = p[3] * 1e-6 - if len(p) == 5: - self.parameter['w_iso'] = p[4] * 1e3 - if dw is not None: - self.dw = dw - - @staticmethod - def _check_old_data(x, d, e, w, h): - if Pake.parameter['x'] is None: - return False - if Pake.parameter['w_iso'] == w and Pake.parameter['delta'] == d and \ - Pake.parameter['eta'] == e and Pake.parameter['half'] == h and \ - Pake.parameter['x'][0] == x[0] and Pake.parameter['x'][1] == x[1]: - return True - return False - - def calc_timesignal(self, tt, p, half=False): - """ - Calculate time signal of pake spectrum - Parameters - ---------- - tt: time array - p: list of parameters [delta, eta, GB, omega_iso] - half: if False, Pake spectrum will be calculated, if True, chemical shift spectrum will be calculated - - Returns - ------- - timesignal - """ - _delta, _eta, _wiso = p - omega = 0.5 * _delta * (self.legendre - _eta * self.axial) - if half: - omega += _wiso - weight = self.powder.wt - if half: - fid_real = np.zeros_like(tt, dtype=float) - fid_imag = np.zeros_like(tt, dtype=float) - for k, v in zip(omega, weight): - pha = 2 * np.pi * k * tt - fid_real += (np.cos(pha)) * v - fid_imag += (np.sin(pha)) * v - fid = 1j * fid_imag - fid += fid_real - else: - fid = np.zeros_like(tt, dtype=float) - for k, v in zip(omega, weight): - fid += np.cos(2 * np.pi * k * tt) * v - return fid - - @staticmethod - def calc_pulse(pw, f): - _phi = 2 * np.pi * f * pw - pulse = ((0.5 * np.pi * np.sin(np.sqrt(0.25 * np.pi ** 2 + 0.5 * _phi ** 2))) / - np.sqrt(0.25 * np.pi ** 2 + 0.25 * _phi ** 2)) ** 1 - - return pulse - - def pake_spectrum(self, x, p=None, half=False): - if p is None: - _gb = self.GB - _pw = self.pw - try: - _delta = self.parameter['delta'] - _eta = self.parameter['eta'] - _wiso = self.parameter['w_iso'] - except KeyError: - _delta = Pake.parameter['delta'] - _eta = Pake.parameter['eta'] - _wiso = Pake.parameter['w_iso'] - else: - _delta = p[0] * 1e3 - _eta = p[1] - _gb = p[2] * 1e3 - _pw = p[3] * 1e-6 - _wiso = p[4] * 1e3 - - # x is time - if abs(x[1] - x[0]) < 1: - if self.dw is None: - self.dw = x[1] - x[0] - t = x - nop = len(x) - isfreq = False - # x is frequency - else: - df = (x[1] - x[0]) - if self.dw is None: - self.dw = 1 / (df * len(x)) - if len(x) != 1 / (self.dw * df): - nop = int(1 / (self.dw * df)) - else: - nop = len(x) - - # avoid calculation for to much points - t = np.arange(0, min(8192, nop)) * self.dw - isfreq = True - - new_data = self._check_old_data((nop, self.dw), _delta, _eta, _wiso, half) - - if new_data: - fid = Pake.parameter['y'] + 0 - Pake.parameter['delta'] = _delta - Pake.parameter['eta'] = _eta - Pake.parameter['w_iso'] = _wiso - Pake.parameter['x'] = (nop, self.dw) - Pake.parameter['half'] = half - self.GB = _gb - self.pw = _pw - fid = self.calc_timesignal(t, [_delta, _eta, _wiso], half=half) - Pake.parameter['y'] = fid + 0 - - - fid *= np.exp(-(_gb * t) ** 2) - - # add zeros to get desired signal length - if len(fid) != nop: - fid = np.append(fid, np.zeros((nop - len(fid))), axis=0) - - spec = np.fft.fftshift(np.fft.fft(fid)) - spec -= np.mean(spec[:10]) - _f = np.fft.fftshift(np.fft.fftfreq(nop, d=self.dw)) - - # take finite pulse length into account - if _pw != 0: - pulse = self.calc_pulse(_pw, _f) - spec *= pulse - - # shift pake spectrum by isotropic shift - if not half: - spec = np.roll(spec, int(self.dw * _wiso * nop)) - - # cut to original frequency range - if isfreq: - # mask = np.ma.masked_inside(_f, min(x), max(x)).mask - # spec = spec[mask] - spec = np.interp(x, _f, spec.real) - - spec.real -= np.mean(spec.real[:10]) - - return spec.real / max(spec.real) - - def pake(self, x, p=None): - return self.pake_spectrum(x, p=p) - - def halfpake(self, x, p=None): - return self.pake_spectrum(x, p=p, half=True) - - -class SecondOrder(object): - parameter = {'c_q': 1e6, 'eta': 0., - 'x': None, 'y': None} - - def __init__(self, samples=200000): - self.powder = Powder(n=samples) - self.dw = None - self.parameter = {} - self.GB = 1000 - self.pw = 1e-6 - self.legendre = 0 - self.axial = 0 - self.coupling = 1 - self.larmor = 2 * np.pi * 100e6 - - def set_parameter(self, p, dw=None, larmor=None, spin=2.5): - self.parameter['c_q'] = 2 * np.pi * p[0] * 1e6 - self.parameter['eta'] = p[1] - self.GB = p[2] * 1e3 - if dw is not None: - self.dw = dw - if larmor is not None: - self.larmor = 2 * np.pi * larmor - self._calc_coupling(2 * np.pi * p[0] * 1e6, spin=spin) - - def _calc_coupling(self, c_q, spin=2.5): - omega_q = c_q / (2 * spin * (2 * spin - 1)) - self.coupling = 1.5 * omega_q ** 2 / self.larmor * (spin * (spin + 1) - 0.75) - - def calc_omega(self, eta, delta): - self._calc_coupling(delta) - cos2phi = np.cos(2 * self.powder.alpha) - cos_theta_square = 0.5 + 0.5 * np.cos(2 * self.powder.beta) - prefactor_a = -3.375 + 2.25 * eta * cos2phi - 0.375 * (eta * cos2phi) ** 2 - prefactor_b = 3.75 - 0.5 * eta ** 2 - 2 * eta * cos2phi + 0.75 * (eta * cos2phi) ** 2 - prefactor_c = -0.375 + (eta ** 2) / 3. - 0.25 * eta * cos2phi - 0.375 * (eta * cos2phi) ** 2 - ret_val = np.zeros_like(cos2phi) - ret_val += prefactor_a * cos_theta_square ** 2 - ret_val += prefactor_b * cos_theta_square - ret_val += prefactor_c - return self.coupling * ret_val - - def calc_timesignal(self, tt, p): - delta, eta = p - omega = self.calc_omega(eta, delta) - weight = self.powder.wt - fid_real = np.zeros_like(tt, dtype=float) - fid_imag = np.zeros_like(tt, dtype=float) - - for o, w in zip(omega, weight): - pha = o * tt - co_pha = np.cos(pha) - si_pha = np.sin(pha) - fid_real += co_pha * w - fid_imag += si_pha * w - - fid = 1j * fid_imag - fid += fid_real - return fid - - def spectrum(self, x, p=None): - if p is None: - p = [self.parameter['c_q'], self.parameter['eta'], self.GB] - if abs(x[1] - x[0]) < 1: - if self.dw is None: - self.dw = x[1] - x[0] - t = x - nop = len(x) - isfreq = False - else: - df = (x[1] - x[0]) - if self.dw is None: - self.dw = 1 / (df * len(x)) - if len(x) != 1 / (self.dw * df): - nop = int(1 / (self.dw * df)) - else: - nop = len(x) - t = np.arange(0, min(8192, nop)) * self.dw - isfreq = True - - fid = self.calc_timesignal(t, p[:-1]) - fid *= np.exp(-(p[-1] * t) ** 2) - - if len(fid) != nop: - fid = np.append(fid, np.zeros((nop - len(fid))), axis=0) - - spec = np.fft.fftshift(np.fft.fft(fid)) - _f = np.fft.fftshift(np.fft.fftfreq(nop, d=self.dw)) - - if isfreq: - mask = np.ma.masked_inside(_f, min(x), max(x)).mask - spec = spec[mask] - - return spec.real - np.mean(spec.real[:10]) - - -def csa(x: np.ndarray, delta: float, eta: float, wiso: float, gb: float, sw: float): - dw = 1 / sw - a, b, _ = crystallites(200000) - bins = 0.5 * (x[1:] + x[:-1]) - bins = np.hstack((np.array([0.5 * (-x[1] + 3 * x[0])]), bins, np.array([0.5 * (3 * x[-1] - x[-2])]))) - - omega = wiso + delta * 0.5 * (3 * np.cos(b) ** 2 - 1 - eta * np.square(np.sin(b)) * np.cos(2 * a)) - - s_left = np.histogram(omega, bins=bins)[0] - s = s_left - - if gb != 0: - apd = np.exp(-4 * np.log(2) * (np.fft.fftshift(np.fft.fftfreq(len(x), d=dw)) / sw) ** 2) * \ - 2 * np.sqrt(np.log(2) / np.pi) / gb - ret_val = np.convolve(s, apd, mode='same') - else: - ret_val = s - - return ret_val / trapz(ret_val, x) - - -def pake(p, x): - dw = 1/p[-1] - a, b, _ = crystallites(200000) - bins = 0.5 * (x[1:] + x[:-1]) - bins = np.hstack((np.array([0.5 * (-x[1] + 3 * x[0])]), bins, np.array([0.5 * (3 * x[-1] - x[-2])]))) - - omega = p[0] * 0.5 * (3*np.cos(b)**2 - 1 - p[1] * np.square(np.sin(b)) * np.cos(2 * a)) - - s_left = np.histogram(omega, bins=bins)[0] - s_right = np.histogram(-omega, bins=bins)[0] - s = s_left + s_right - - if p[2] != 0: - apd = np.exp(-4 * np.log(2) * (np.fft.fftshift(np.fft.fftfreq(len(x), d=dw)) / p[2]) ** 2) * \ - 2 * np.sqrt(np.log(2) / np.pi) / p[2] - ret_val = np.convolve(s, apd, mode='same') - else: - ret_val = s - - return ret_val/trapz(ret_val, x) - - -def sec_order(p, x, spin=2.5): - dw = 1/p[-1] - a, b, _ = crystallites(200000) - bins = 0.5 * (x[1:] + x[:-1]) - bins = np.hstack((np.array([0.5 * (-x[1] + 3 * x[0])]), bins, np.array([0.5 * (3 * x[-1] - x[-2])]))) - - omega_q = 2 * np.pi * p[0] / (2*spin * (2*spin - 1)) - coupling = 1.5 * (omega_q**2 / (2 * np.pi *p[3])) * (spin*(spin + 1) - 0.75) - - cos2phi = np.cos(2 * a) - cos_theta_square = 0.5+0.5*np.cos(2*b) - prefactor_a = -3.375 + 2.25*p[1] * cos2phi - 0.375 * (p[1] * cos2phi)**2 - prefactor_b = 3.75 - 0.5 * p[1]**2 - 2*p[1]*cos2phi + 0.75 * (p[1]*cos2phi)**2 - prefactor_c = -0.375 + (p[1]**2)/3. - 0.25*p[1]*cos2phi - 0.375 * (p[1]*cos2phi)**2 - orient = np.zeros_like(cos2phi) - orient += prefactor_a * cos_theta_square ** 2 - orient += prefactor_b * cos_theta_square - orient += prefactor_c - - omega = coupling * orient - - s = np.histogram(omega/(2*np.pi), bins=bins)[0] - - if p[2] != 0: - apd = np.exp(-4 * np.log(2) * (np.fft.fftshift(np.fft.fftfreq(len(x), d=dw)) / p[2]) ** 2) * \ - 2 * np.sqrt(np.log(2) / np.pi) / p[2] - ret_val = np.convolve(s, apd, mode='same') - else: - ret_val = s - - return ret_val / trapz(ret_val, x) diff --git a/nmreval/models/gengamma.py b/nmreval/models/gengamma.py deleted file mode 100644 index 0d332ef..0000000 --- a/nmreval/models/gengamma.py +++ /dev/null @@ -1,268 +0,0 @@ -import numpy as np -from scipy.special import gammaln -from ..math.logfourier import logft - -stepsize = 0.2 # 0.05 -span1 = 20 -span2 = 30 - - -class GeneralGamma(object): - lower_b = 20 - upper_b = 20 - dx = 0.2 - - @staticmethod - def gga_dist(tau, tau0, alpha, beta): - b_to_a = beta / alpha - norm = np.exp(gammaln(b_to_a) - b_to_a * np.log(b_to_a)) / alpha - t_to_t0 = tau / tau0 - ret_val = np.exp(-b_to_a * t_to_t0 ** alpha) * t_to_t0 ** beta - - return ret_val / norm - - @staticmethod - def gga_ew_dist(tau, tau0, alpha, beta, sigma, gamma): - if gamma == beta: - return GeneralGamma.gga_dist(tau, tau0, alpha, beta) - b_to_a = beta / alpha - g_to_a = gamma / alpha - t_to_t0 = tau / tau0 - norm = (np.exp(gammaln(b_to_a)) + sigma**(gamma-beta) * np.exp(gammaln(g_to_a) + (b_to_a-g_to_a)*np.log(b_to_a))) / np.exp(b_to_a*np.log(b_to_a)) / alpha - - ret_val = np.exp(-b_to_a * t_to_t0**alpha) * t_to_t0**beta * (1 + (t_to_t0*sigma)**(gamma-beta)) - - return ret_val / norm - - @staticmethod - def ggb_dist(tau, tau0, a, b): - norm = a * (1+b) * np.sin(np.pi*b/(1+b)) * b**(b/(1+b)) / np.pi - ret_val = b * (tau/tau0)**a + (tau/tau0)**(-a*b) - - return norm / ret_val - - @staticmethod - def _gg_time(t, tau0, *args, **kwargs): - logtau = np.log(tau0) - steps = np.arange(logtau - GeneralGamma.lower_b, logtau + GeneralGamma.upper_b, GeneralGamma.dx) - taus = np.exp(steps) - ret_val = np.zeros_like(t) - dist = {'gga': GeneralGamma.gga_dist, - 'gga_ew': GeneralGamma.gga_ew_dist, - 'ggb': GeneralGamma.ggb_dist}[kwargs.pop('mode', 'gga')] - gtau = dist(taus, tau0, *args) - for i, xval in enumerate(t): - y = np.exp(- xval / taus) - y *= gtau - y = y[1:] + y[:-1] - ret_val[i] = np.sum(y) * GeneralGamma.dx / 2 - return ret_val - - @staticmethod - def ggaew_b_freq(f, tau0, alpha, beta, sigma, gamma, tau1, a, b, r, dec=5): - t = np.logspace(np.log10(1 / max(f)) - dec, np.log10(1 / min(f)) + dec, num=int(len(f) * (0.5 * dec))) - phi_a = GeneralGamma.ggaew(t, tau0, alpha, beta, sigma, gamma) - phi_b = GeneralGamma.ggb(t, tau1, a, b) - temp = phi_a * (1 - r + r * phi_b) - - ret_val = logft(t, temp, new_x=2 * np.pi * f)[1].y - - return ret_val * f * 2 * np.pi - - @staticmethod - def gga_b_freq(f, tau0, alpha, beta, tau1, a, b, r, dec=5): - t = np.logspace(np.log10(1 / max(f)) - dec, np.log10(1 / min(f)) + dec, num=int(len(f) * (0.5 * dec))) - phi_a = GeneralGamma.gga(t, tau0, alpha, beta) - phi_b = GeneralGamma.ggb(t, tau1, a, b) - temp = phi_a * (1 - r + r * phi_b) - - ret_val = logft(t, temp, new_x=2 * np.pi * f)[1].y - - return ret_val * f * 2 * np.pi - - @staticmethod - def gga(t, tau0, alpha, beta): - return GeneralGamma._gg_time(t, tau0, alpha, beta, mode='gga') - - @staticmethod - def ggaew(t, tau0, alpha, beta, sigma, gamma): - return GeneralGamma._gg_time(t, tau0, alpha, beta, sigma, gamma, mode='gga_ew') - - @staticmethod - def ggb(t, tau0, a, b): - return GeneralGamma._gg_time(t, tau0, a, b, mode='ggb') - - @staticmethod - def ggaew_b(t, tau0, alpha, beta, sigma, gamma, tau1, a, b, r): - phi_a = GeneralGamma.ggaew(t, tau0, alpha, beta, sigma, gamma) - phi_b = GeneralGamma.ggb(t, tau1, a, b) - ret_val = phi_a * (1 - r + r * phi_b) - return ret_val - - @staticmethod - def gga_b(t, tau0, alpha, beta, tau1, a, b, r): - phi_a = GeneralGamma.gga(t, tau0, alpha, beta) - phi_b = GeneralGamma.ggb(t, tau1, a, b) - ret_val = phi_a * (1 - r + r * phi_b) - return ret_val - - -class FitGG(object): - name = 'Alpha + Beta + EW' - type = 'Gamma-Functions' - equation = r'A*\Phi_{\alpha,EW} * [1 - C + C*\Phi_{\beta}] + B' - params = ['A', 'B', - r'\tau_{\alpha}', r'\alpha', r'\beta', '\sigma', '\gamma', - r'\tau_{\beta}', 'a', 'b', 'C'] - - @staticmethod - def func(p, x): - amp, base, tau0, alpha, beta, sigma, gamma, tau1, a, b, c = p - phi_a = GeneralGamma.ggaew(x, tau0, alpha, beta, sigma, gamma) - phi_b = GeneralGamma.ggb(x, tau1, a, b) - ret_val = amp * phi_a * (1 - c + c * phi_b) + base - return ret_val - - -# Definiere Funktionen # -def glntau1_td(ttime, tau, alpha, beta): - lnx = np.log(tau) + span1 - intmin = np.log(tau) - span2 - steps = np.arange(lnx, intmin, -stepsize) - explnx = np.exp(steps) - betatoalpha = beta / alpha - logtau = np.log(tau) - if betatoalpha > 80: - norm = np.exp(.5 * np.log(2 * np.pi / betatoalpha) - betatoalpha) / alpha - else: - norm = np.exp(gammaln(betatoalpha)) / alpha / np.power(betatoalpha, betatoalpha) - y = np.exp(-np.exp((steps - logtau) * alpha) * betatoalpha) * np.power(explnx / tau, beta) * np.exp(-ttime / explnx) - y = y[1:] + y[:-1] - intval = np.sum(y) / 2 - intval = intval * stepsize / norm - return intval - - -def gga(t, tau0, alpha, beta): - logtau = np.log(tau0) - stepsize = 0.2 - steps = np.arange(logtau - 20, logtau + 20, stepsize) - taus = np.exp(steps)/tau0 - betatoalpha = beta / alpha - norm = np.exp(gammaln(betatoalpha) - betatoalpha*np.log(betatoalpha)) / alpha - ret_val = np.zeros_like(t) - gtau = np.exp(-taus ** alpha * betatoalpha) * taus ** beta - for i, xval in enumerate(t): - # exponent = -taus**alpha * betatoalpha - xval/taus/tau0 - y = np.exp(- xval/taus/tau0) - y *= gtau - y = y[1:] + y[:-1] - ret_val[i] = np.sum(y) * stepsize / norm / 2 - return ret_val - - -def ggaew(t, tau0, alpha, beta, sigma, gamma): - logtau = np.log(tau0) - stepsize = 0.2 - steps = np.arange(logtau - 20, logtau + 20, stepsize) - taus = np.exp(steps) / tau0 - q1 = beta / alpha - q2 = gamma / alpha - norm = (np.exp(gammaln(q1)) + sigma**(gamma-beta) * np.exp((q1-q2)*np.log(q1)) * np.exp(gammaln(q2))) / alpha / np.exp(q1*np.log(q1)) - ret_val = np.empty_like(t) - gtau = np.exp(-taus**alpha * q1) * taus**beta * (1 + (taus*sigma)**(gamma-beta)) - for i, xval in enumerate(t): - y = np.exp(-xval/taus/tau0) - y *= gtau - y = y[1:] + y[:-1] - ret_val[i] = np.sum(y) * stepsize / norm / 2 - return ret_val - - -def ggaew_b(t, tau0, alpha, beta, sigma, gamma, tau1, a, b, r): - phi_a = ggaew(t, tau0, alpha, beta,sigma, gamma) - phi_b = ggb(t, tau1, a, b) - ret_val = phi_a * (1-r + r*phi_b) - return ret_val - - -def ggb(t, tau0, a, b): - logtau = np.log(tau0) - stepsize = 0.2 - steps = np.arange(logtau - 20, logtau + 20, stepsize) - taus = np.exp(steps) / tau0 - norm = np.pi / (a*(1+b)) / b**(b/(1+b)) / np.sin(np.pi*b / (1+b)) - ret_val = np.empty_like(t) - gtau = 1. / (b * taus**a + taus**(-b*a)) - for i, xval in enumerate(t): - y = np.exp(-xval / taus / tau0) - y *= gtau - y = y[1:] + y[:-1] - ret_val[i] = np.sum(y) * stepsize / norm / 2 - return ret_val - - -def glntau2_td(ttime, tau, alpha, beta, sigma, gam): - intval = 0 - lnx = np.log(tau) + span1 - intmin = np.log(tau) - span2 - steps = np.arange(lnx, intmin, -stepsize) - explnx = np.exp(steps) - logtau = np.log(tau) - q1 = beta / alpha - q2 = gam / alpha - - if q2 > 80: - norm = (np.exp(.5 * np.log(2 * np.pi / q1) - q1) + np.power(sigma, alpha * (q2 - q1)) * np.power(q2 / q1, - -q2) * np.exp( - .5 * np.log(2 * np.PI / q2) - q2)) / alpha - elif q1 > 80: - norm = (np.exp(.5 * np.log(2 * np.pi / q1) - q1) + np.power(sigma, alpha * (q2 - q1)) * np.power(q2 / q1, - -q2) * np.exp( - gammaln(q2)) * np.power(q1, -q1)) / alpha - else: - norm = (np.exp(gammaln(q1)) + np.power(sigma, gam - beta) * np.power(q1, q1 - q2) * np.exp(gammaln(q2))) / ( - alpha * np.power(q1, q1)) - y = np.exp(-np.exp((steps - logtau) * alpha) * q1) * np.power(explnx / tau, beta) * ( - 1 + np.power(explnx * sigma / tau, gam - beta)) * np.exp(-ttime / explnx) - y = y[1:] + y[:-1] - intval = np.sum(y) / 2 - intval = intval * stepsize / norm - return intval - - -def glnbeta_td(ttime, tau, a, b): - intval = 0 - lnx = np.log(tau) + span1 - intmin = np.log(tau) - span2 - steps = np.arange(lnx, intmin, -stepsize) - explnx = np.exp(steps) - norm = np.pi / (a * (1 + b)) / np.power(b, b / (1. + b)) / np.sin(np.pi * b / (1. + b)) - y = 1. / (b * np.power(explnx / tau, a) + np.power(explnx / tau, -(b * a))) * np.exp(-ttime / explnx) - y = y[1:] + y[:-1] - intval = np.sum(y) / 2 - - intval = intval * stepsize / norm - return intval - - -def g2(p, x): - ret_val = np.empty(np.shape(x)) - for i, xval in enumerate(x): - # fkt1 = glntau2_td(xval, p[1], p[2], p[3], p[4], p[5]) - # fkt1 = glntau1_td(xval, p[1], p[2], p[3]) - fkt1 = glntau2_td(xval, p[1], p[2], p[3], p[4], p[5]) - fkt2 = glnbeta_td(xval, p[6], p[7], p[8]) - # ret_val[i] = (fkt1 * ((1 - p[4]) + p[4] * fkt2) * p[0]) + np.abs(p[9]) * np.exp(-(xval/p[10])**p[11]) + p[8] - ret_val[i] = fkt1 * (1-p[0] + p[0]*fkt2) - return ret_val - - -def g1(p, x): - ret_val = np.empty(np.shape(x)) - for i, xval in enumerate(x): - # fkt1 = glntau1_td(xval,p[1],p[2],p[3]) - fkt1 = glntau2_td(xval, p[1], p[2], p[3], p[11], p[12]) - fkt2 = glnbeta_td(xval, p[5], p[6], p[7]) - ret_val[i] = p[0] * (fkt1 * ((1 - p[4]) + p[4] * fkt2)) + np.abs(p[8]) * np.exp(-(xval / p[9]) ** p[10]) - return ret_val diff --git a/requirements.txt b/requirements.txt index 96d9f90..c035f4f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,8 @@ matplotlib numpy scipy +pyqt +h5py pyqtgraph bsddb3 -h5py -pyqt diff --git a/resources/_ui/fitcreationdialog.ui b/resources/_ui/fitcreationdialog.ui deleted file mode 100644 index 689327a..0000000 --- a/resources/_ui/fitcreationdialog.ui +++ /dev/null @@ -1,419 +0,0 @@ - - - Dialog - - - - 0 - 0 - 614 - 776 - - - - Dialog - - - - 3 - - - 3 - - - 3 - - - 3 - - - 3 - - - - - Description - - - true - - - false - - - - 3 - - - 3 - - - 3 - - - 3 - - - 3 - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 3 - - - - - - - - - - - Group - - - - - - - Name - - - name_lineedit - - - - - - - - - - Equation - - - - - - - - - - - - - Variables - - - true - - - false - - - - 3 - - - 3 - - - 3 - - - 3 - - - 3 - - - - - - 3 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - QAbstractItemView::SingleSelection - - - QAbstractItemView::SelectRows - - - 4 - - - - Variable - - - - - Name - - - - - Lower bound - - - - - Upper bound - - - - - - - - Add parameter - - - Qt::ToolButtonTextBesideIcon - - - false - - - Qt::RightArrow - - - - - - - - - - - - - Multiple choice part - - - true - - - false - - - - 3 - - - 3 - - - 3 - - - 3 - - - 3 - - - - - - 3 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Add gyromagnetic ratios - - - - - - - QTabWidget::West - - - true - - - - - - - Add selection - - - Qt::ToolButtonTextBesideIcon - - - Qt::RightArrow - - - - - - - - - - - - - Available namespace - - - true - - - false - - - - - - - 0 - 0 - - - - - - - - - - - - 3 - - - 3 - - - 3 - - - 3 - - - 3 - - - - - Function y = func(x) - - - - - - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - QNamespaceWidget - QWidget -

..lib.namespace
- 1 - - - CodeEditor - QPlainTextEdit -
..lib.codeeditor
-
- - - - - buttonBox - accepted() - Dialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - Dialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff --git a/nmreval/gui_qt/Qt.py b/src/gui_qt/Qt.py similarity index 81% rename from nmreval/gui_qt/Qt.py rename to src/gui_qt/Qt.py index 1a85709..42e02e7 100644 --- a/nmreval/gui_qt/Qt.py +++ b/src/gui_qt/Qt.py @@ -1,7 +1,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets, QtPrintSupport -# from PySide2 import QtCore, QtGui, QtWidgets +# from PySide2 import QtCore, QtGui, QtWidgets, QtPrintSupport # QtCore.pyqtSignal = QtCore.Signal # QtCore.pyqtProperty = QtCore.Property # QtCore.pyqtSlot = QtCore.Slot diff --git a/nmreval/gui_qt/__init__.py b/src/gui_qt/__init__.py similarity index 89% rename from nmreval/gui_qt/__init__.py rename to src/gui_qt/__init__.py index cd017b5..30ce690 100644 --- a/nmreval/gui_qt/__init__.py +++ b/src/gui_qt/__init__.py @@ -1,6 +1,7 @@ +from nmreval.configs import read_configuration + from .Qt import QtWidgets from .lib.styles import MyProxyStyle -from ..configs import read_configuration class App(QtWidgets.QApplication): diff --git a/nmreval/gui_qt/_py/__init__.py b/src/gui_qt/_py/__init__.py similarity index 100% rename from nmreval/gui_qt/_py/__init__.py rename to src/gui_qt/_py/__init__.py diff --git a/nmreval/gui_qt/_py/agroptiondialog.py b/src/gui_qt/_py/agroptiondialog.py similarity index 100% rename from nmreval/gui_qt/_py/agroptiondialog.py rename to src/gui_qt/_py/agroptiondialog.py diff --git a/nmreval/gui_qt/_py/apod_dialog.py b/src/gui_qt/_py/apod_dialog.py similarity index 100% rename from nmreval/gui_qt/_py/apod_dialog.py rename to src/gui_qt/_py/apod_dialog.py diff --git a/nmreval/gui_qt/_py/asciidialog.py b/src/gui_qt/_py/asciidialog.py similarity index 100% rename from nmreval/gui_qt/_py/asciidialog.py rename to src/gui_qt/_py/asciidialog.py diff --git a/nmreval/gui_qt/_py/axisConfigTemplate.py b/src/gui_qt/_py/axisConfigTemplate.py similarity index 100% rename from nmreval/gui_qt/_py/axisConfigTemplate.py rename to src/gui_qt/_py/axisConfigTemplate.py diff --git a/nmreval/gui_qt/_py/baseline_dialog.py b/src/gui_qt/_py/baseline_dialog.py similarity index 100% rename from nmreval/gui_qt/_py/baseline_dialog.py rename to src/gui_qt/_py/baseline_dialog.py diff --git a/nmreval/gui_qt/_py/basewindow.py b/src/gui_qt/_py/basewindow.py similarity index 100% rename from nmreval/gui_qt/_py/basewindow.py rename to src/gui_qt/_py/basewindow.py diff --git a/nmreval/gui_qt/_py/bdsdialog.py b/src/gui_qt/_py/bdsdialog.py similarity index 100% rename from nmreval/gui_qt/_py/bdsdialog.py rename to src/gui_qt/_py/bdsdialog.py diff --git a/nmreval/gui_qt/_py/color_palette.py b/src/gui_qt/_py/color_palette.py similarity index 100% rename from nmreval/gui_qt/_py/color_palette.py rename to src/gui_qt/_py/color_palette.py diff --git a/nmreval/gui_qt/_py/coupling_calculator.py b/src/gui_qt/_py/coupling_calculator.py similarity index 100% rename from nmreval/gui_qt/_py/coupling_calculator.py rename to src/gui_qt/_py/coupling_calculator.py diff --git a/nmreval/gui_qt/_py/coupling_t1_from_tau.py b/src/gui_qt/_py/coupling_t1_from_tau.py similarity index 100% rename from nmreval/gui_qt/_py/coupling_t1_from_tau.py rename to src/gui_qt/_py/coupling_t1_from_tau.py diff --git a/nmreval/gui_qt/_py/datawidget.py b/src/gui_qt/_py/datawidget.py similarity index 100% rename from nmreval/gui_qt/_py/datawidget.py rename to src/gui_qt/_py/datawidget.py diff --git a/nmreval/gui_qt/_py/dscfile_dialog.py b/src/gui_qt/_py/dscfile_dialog.py similarity index 100% rename from nmreval/gui_qt/_py/dscfile_dialog.py rename to src/gui_qt/_py/dscfile_dialog.py diff --git a/nmreval/gui_qt/_py/editsignalwidget.py b/src/gui_qt/_py/editsignalwidget.py similarity index 100% rename from nmreval/gui_qt/_py/editsignalwidget.py rename to src/gui_qt/_py/editsignalwidget.py diff --git a/nmreval/gui_qt/_py/eval_expr_dialog.py b/src/gui_qt/_py/eval_expr_dialog.py similarity index 100% rename from nmreval/gui_qt/_py/eval_expr_dialog.py rename to src/gui_qt/_py/eval_expr_dialog.py diff --git a/nmreval/gui_qt/_py/evalexpression.py b/src/gui_qt/_py/evalexpression.py similarity index 100% rename from nmreval/gui_qt/_py/evalexpression.py rename to src/gui_qt/_py/evalexpression.py diff --git a/nmreval/gui_qt/_py/expandablewidget.py b/src/gui_qt/_py/expandablewidget.py similarity index 100% rename from nmreval/gui_qt/_py/expandablewidget.py rename to src/gui_qt/_py/expandablewidget.py diff --git a/nmreval/gui_qt/_py/exportConfigTemplate.py b/src/gui_qt/_py/exportConfigTemplate.py similarity index 100% rename from nmreval/gui_qt/_py/exportConfigTemplate.py rename to src/gui_qt/_py/exportConfigTemplate.py diff --git a/nmreval/gui_qt/_py/fcreader.py b/src/gui_qt/_py/fcreader.py similarity index 100% rename from nmreval/gui_qt/_py/fcreader.py rename to src/gui_qt/_py/fcreader.py diff --git a/nmreval/gui_qt/_py/filedialog.py b/src/gui_qt/_py/filedialog.py similarity index 100% rename from nmreval/gui_qt/_py/filedialog.py rename to src/gui_qt/_py/filedialog.py diff --git a/src/gui_qt/_py/fitcreationdialog.py b/src/gui_qt/_py/fitcreationdialog.py new file mode 100644 index 0000000..d1c6075 --- /dev/null +++ b/src/gui_qt/_py/fitcreationdialog.py @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'resources/_ui/fitcreationdialog.ui' +# +# Created by: PyQt5 UI code generator 5.15.4 +# +# WARNING: Any manual changes made to this file will be lost when pyuic5 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt5 import QtCore, QtGui, QtWidgets + + +class Ui_Dialog(object): + def setupUi(self, Dialog): + Dialog.setObjectName("Dialog") + Dialog.resize(773, 633) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.MinimumExpanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(Dialog.sizePolicy().hasHeightForWidth()) + Dialog.setSizePolicy(sizePolicy) + self.verticalLayout = QtWidgets.QVBoxLayout(Dialog) + self.verticalLayout.setObjectName("verticalLayout") + self.splitter = QtWidgets.QSplitter(Dialog) + self.splitter.setOrientation(QtCore.Qt.Vertical) + self.splitter.setObjectName("splitter") + self.tabWidget = QtWidgets.QTabWidget(self.splitter) + self.tabWidget.setObjectName("tabWidget") + self.description_box = QtWidgets.QWidget() + self.description_box.setObjectName("description_box") + self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.description_box) + self.verticalLayout_2.setContentsMargins(3, 3, 3, 3) + self.verticalLayout_2.setSpacing(0) + self.verticalLayout_2.setObjectName("verticalLayout_2") + self.tabWidget.addTab(self.description_box, "") + self.args_box = QtWidgets.QWidget() + self.args_box.setObjectName("args_box") + self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.args_box) + self.verticalLayout_3.setContentsMargins(3, 3, 3, 3) + self.verticalLayout_3.setSpacing(0) + self.verticalLayout_3.setObjectName("verticalLayout_3") + self.tabWidget.addTab(self.args_box, "") + self.kwargs_box = QtWidgets.QWidget() + self.kwargs_box.setObjectName("kwargs_box") + self.verticalLayout_5 = QtWidgets.QVBoxLayout(self.kwargs_box) + self.verticalLayout_5.setObjectName("verticalLayout_5") + self.tabWidget.addTab(self.kwargs_box, "") + self.namespace_box = QtWidgets.QWidget() + self.namespace_box.setObjectName("namespace_box") + self.verticalLayout_6 = QtWidgets.QVBoxLayout(self.namespace_box) + self.verticalLayout_6.setObjectName("verticalLayout_6") + self.tabWidget.addTab(self.namespace_box, "") + self.plainTextEdit = CodeEditor(self.splitter) + self.plainTextEdit.setEnabled(True) + self.plainTextEdit.setObjectName("plainTextEdit") + self.verticalLayout.addWidget(self.splitter) + self.buttonBox = QtWidgets.QDialogButtonBox(Dialog) + self.buttonBox.setOrientation(QtCore.Qt.Horizontal) + self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok) + self.buttonBox.setObjectName("buttonBox") + self.verticalLayout.addWidget(self.buttonBox) + + self.retranslateUi(Dialog) + self.tabWidget.setCurrentIndex(0) + self.buttonBox.accepted.connect(Dialog.accept) + self.buttonBox.rejected.connect(Dialog.reject) + QtCore.QMetaObject.connectSlotsByName(Dialog) + + def retranslateUi(self, Dialog): + _translate = QtCore.QCoreApplication.translate + Dialog.setWindowTitle(_translate("Dialog", "Create fit function")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.description_box), _translate("Dialog", "Description")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.args_box), _translate("Dialog", "Variables")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.kwargs_box), _translate("Dialog", "Multiple choice")) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.namespace_box), _translate("Dialog", "Available Functions")) +from ..lib.codeeditor import CodeEditor diff --git a/nmreval/gui_qt/_py/fitdialog.py b/src/gui_qt/_py/fitdialog.py similarity index 100% rename from nmreval/gui_qt/_py/fitdialog.py rename to src/gui_qt/_py/fitdialog.py diff --git a/nmreval/gui_qt/_py/fitdialog_window.py b/src/gui_qt/_py/fitdialog_window.py similarity index 100% rename from nmreval/gui_qt/_py/fitdialog_window.py rename to src/gui_qt/_py/fitdialog_window.py diff --git a/nmreval/gui_qt/_py/fitfunctionwidget.py b/src/gui_qt/_py/fitfunctionwidget.py similarity index 100% rename from nmreval/gui_qt/_py/fitfunctionwidget.py rename to src/gui_qt/_py/fitfunctionwidget.py diff --git a/nmreval/gui_qt/_py/fitfuncwidget.py b/src/gui_qt/_py/fitfuncwidget.py similarity index 100% rename from nmreval/gui_qt/_py/fitfuncwidget.py rename to src/gui_qt/_py/fitfuncwidget.py diff --git a/nmreval/gui_qt/_py/fitfuncwidget_old.py b/src/gui_qt/_py/fitfuncwidget_old.py similarity index 100% rename from nmreval/gui_qt/_py/fitfuncwidget_old.py rename to src/gui_qt/_py/fitfuncwidget_old.py diff --git a/nmreval/gui_qt/_py/fitmodelfixwidget.py b/src/gui_qt/_py/fitmodelfixwidget.py similarity index 100% rename from nmreval/gui_qt/_py/fitmodelfixwidget.py rename to src/gui_qt/_py/fitmodelfixwidget.py diff --git a/nmreval/gui_qt/_py/fitmodelwidget.py b/src/gui_qt/_py/fitmodelwidget.py similarity index 100% rename from nmreval/gui_qt/_py/fitmodelwidget.py rename to src/gui_qt/_py/fitmodelwidget.py diff --git a/nmreval/gui_qt/_py/fitparametertable.py b/src/gui_qt/_py/fitparametertable.py similarity index 100% rename from nmreval/gui_qt/_py/fitparametertable.py rename to src/gui_qt/_py/fitparametertable.py diff --git a/nmreval/gui_qt/_py/fitparameterwidget.py b/src/gui_qt/_py/fitparameterwidget.py similarity index 100% rename from nmreval/gui_qt/_py/fitparameterwidget.py rename to src/gui_qt/_py/fitparameterwidget.py diff --git a/nmreval/gui_qt/_py/fitresult.py b/src/gui_qt/_py/fitresult.py similarity index 100% rename from nmreval/gui_qt/_py/fitresult.py rename to src/gui_qt/_py/fitresult.py diff --git a/nmreval/gui_qt/_py/ftdialog.py b/src/gui_qt/_py/ftdialog.py similarity index 100% rename from nmreval/gui_qt/_py/ftdialog.py rename to src/gui_qt/_py/ftdialog.py diff --git a/nmreval/gui_qt/_py/function_tree_widget.py b/src/gui_qt/_py/function_tree_widget.py similarity index 100% rename from nmreval/gui_qt/_py/function_tree_widget.py rename to src/gui_qt/_py/function_tree_widget.py diff --git a/nmreval/gui_qt/_py/gol.py b/src/gui_qt/_py/gol.py similarity index 100% rename from nmreval/gui_qt/_py/gol.py rename to src/gui_qt/_py/gol.py diff --git a/nmreval/gui_qt/_py/gracemsgdialog.py b/src/gui_qt/_py/gracemsgdialog.py similarity index 100% rename from nmreval/gui_qt/_py/gracemsgdialog.py rename to src/gui_qt/_py/gracemsgdialog.py diff --git a/nmreval/gui_qt/_py/gracereader.py b/src/gui_qt/_py/gracereader.py similarity index 100% rename from nmreval/gui_qt/_py/gracereader.py rename to src/gui_qt/_py/gracereader.py diff --git a/nmreval/gui_qt/_py/graph.py b/src/gui_qt/_py/graph.py similarity index 100% rename from nmreval/gui_qt/_py/graph.py rename to src/gui_qt/_py/graph.py diff --git a/nmreval/gui_qt/_py/guidelinewidget.py b/src/gui_qt/_py/guidelinewidget.py similarity index 100% rename from nmreval/gui_qt/_py/guidelinewidget.py rename to src/gui_qt/_py/guidelinewidget.py diff --git a/nmreval/gui_qt/_py/hdftree.py b/src/gui_qt/_py/hdftree.py similarity index 100% rename from nmreval/gui_qt/_py/hdftree.py rename to src/gui_qt/_py/hdftree.py diff --git a/nmreval/gui_qt/_py/integral_widget.py b/src/gui_qt/_py/integral_widget.py similarity index 100% rename from nmreval/gui_qt/_py/integral_widget.py rename to src/gui_qt/_py/integral_widget.py diff --git a/nmreval/gui_qt/_py/integratederive_dialog.py b/src/gui_qt/_py/integratederive_dialog.py similarity index 100% rename from nmreval/gui_qt/_py/integratederive_dialog.py rename to src/gui_qt/_py/integratederive_dialog.py diff --git a/nmreval/gui_qt/_py/interpol_dialog.py b/src/gui_qt/_py/interpol_dialog.py similarity index 100% rename from nmreval/gui_qt/_py/interpol_dialog.py rename to src/gui_qt/_py/interpol_dialog.py diff --git a/nmreval/gui_qt/_py/lineedit_dialog.py b/src/gui_qt/_py/lineedit_dialog.py similarity index 100% rename from nmreval/gui_qt/_py/lineedit_dialog.py rename to src/gui_qt/_py/lineedit_dialog.py diff --git a/nmreval/gui_qt/_py/mean_form.py b/src/gui_qt/_py/mean_form.py similarity index 100% rename from nmreval/gui_qt/_py/mean_form.py rename to src/gui_qt/_py/mean_form.py diff --git a/nmreval/gui_qt/_py/meandialog.py b/src/gui_qt/_py/meandialog.py similarity index 100% rename from nmreval/gui_qt/_py/meandialog.py rename to src/gui_qt/_py/meandialog.py diff --git a/nmreval/gui_qt/_py/modelwidget.py b/src/gui_qt/_py/modelwidget.py similarity index 100% rename from nmreval/gui_qt/_py/modelwidget.py rename to src/gui_qt/_py/modelwidget.py diff --git a/nmreval/gui_qt/_py/move_dialog.py b/src/gui_qt/_py/move_dialog.py similarity index 100% rename from nmreval/gui_qt/_py/move_dialog.py rename to src/gui_qt/_py/move_dialog.py diff --git a/nmreval/gui_qt/_py/namespace_widget.py b/src/gui_qt/_py/namespace_widget.py similarity index 100% rename from nmreval/gui_qt/_py/namespace_widget.py rename to src/gui_qt/_py/namespace_widget.py diff --git a/nmreval/gui_qt/_py/option_selection.py b/src/gui_qt/_py/option_selection.py similarity index 100% rename from nmreval/gui_qt/_py/option_selection.py rename to src/gui_qt/_py/option_selection.py diff --git a/nmreval/gui_qt/_py/parameterform.py b/src/gui_qt/_py/parameterform.py similarity index 100% rename from nmreval/gui_qt/_py/parameterform.py rename to src/gui_qt/_py/parameterform.py diff --git a/nmreval/gui_qt/_py/phase_corr_dialog.py b/src/gui_qt/_py/phase_corr_dialog.py similarity index 100% rename from nmreval/gui_qt/_py/phase_corr_dialog.py rename to src/gui_qt/_py/phase_corr_dialog.py diff --git a/nmreval/gui_qt/_py/plotConfigTemplate.py b/src/gui_qt/_py/plotConfigTemplate.py similarity index 100% rename from nmreval/gui_qt/_py/plotConfigTemplate.py rename to src/gui_qt/_py/plotConfigTemplate.py diff --git a/nmreval/gui_qt/_py/pokemon.py b/src/gui_qt/_py/pokemon.py similarity index 100% rename from nmreval/gui_qt/_py/pokemon.py rename to src/gui_qt/_py/pokemon.py diff --git a/nmreval/gui_qt/_py/propwidget.py b/src/gui_qt/_py/propwidget.py similarity index 100% rename from nmreval/gui_qt/_py/propwidget.py rename to src/gui_qt/_py/propwidget.py diff --git a/nmreval/gui_qt/_py/ptstab.py b/src/gui_qt/_py/ptstab.py similarity index 100% rename from nmreval/gui_qt/_py/ptstab.py rename to src/gui_qt/_py/ptstab.py diff --git a/nmreval/gui_qt/_py/qfiledialog.py b/src/gui_qt/_py/qfiledialog.py similarity index 100% rename from nmreval/gui_qt/_py/qfiledialog.py rename to src/gui_qt/_py/qfiledialog.py diff --git a/nmreval/gui_qt/_py/save_fit_parameter.py b/src/gui_qt/_py/save_fit_parameter.py similarity index 100% rename from nmreval/gui_qt/_py/save_fit_parameter.py rename to src/gui_qt/_py/save_fit_parameter.py diff --git a/nmreval/gui_qt/_py/save_fitmodel_dialog.py b/src/gui_qt/_py/save_fitmodel_dialog.py similarity index 100% rename from nmreval/gui_qt/_py/save_fitmodel_dialog.py rename to src/gui_qt/_py/save_fitmodel_dialog.py diff --git a/nmreval/gui_qt/_py/save_options.py b/src/gui_qt/_py/save_options.py similarity index 100% rename from nmreval/gui_qt/_py/save_options.py rename to src/gui_qt/_py/save_options.py diff --git a/nmreval/gui_qt/_py/saveoptions.py b/src/gui_qt/_py/saveoptions.py similarity index 100% rename from nmreval/gui_qt/_py/saveoptions.py rename to src/gui_qt/_py/saveoptions.py diff --git a/nmreval/gui_qt/_py/sdmodelwidget.py b/src/gui_qt/_py/sdmodelwidget.py similarity index 100% rename from nmreval/gui_qt/_py/sdmodelwidget.py rename to src/gui_qt/_py/sdmodelwidget.py diff --git a/nmreval/gui_qt/_py/selection_widget.py b/src/gui_qt/_py/selection_widget.py similarity index 100% rename from nmreval/gui_qt/_py/selection_widget.py rename to src/gui_qt/_py/selection_widget.py diff --git a/nmreval/gui_qt/_py/setbyfunction_dialog.py b/src/gui_qt/_py/setbyfunction_dialog.py similarity index 100% rename from nmreval/gui_qt/_py/setbyfunction_dialog.py rename to src/gui_qt/_py/setbyfunction_dialog.py diff --git a/nmreval/gui_qt/_py/shift_scale_dialog.py b/src/gui_qt/_py/shift_scale_dialog.py similarity index 99% rename from nmreval/gui_qt/_py/shift_scale_dialog.py rename to src/gui_qt/_py/shift_scale_dialog.py index b8605e5..7997c30 100644 --- a/nmreval/gui_qt/_py/shift_scale_dialog.py +++ b/src/gui_qt/_py/shift_scale_dialog.py @@ -310,5 +310,5 @@ class Ui_shift_dialog(object): self.overwrite_checkbox.setText(_translate("shift_dialog", "Overwrite data")) self.data_newgraph.setText(_translate("shift_dialog", "New graph")) self.values_newgraph.setText(_translate("shift_dialog", "New graph")) -from ..lib.utils import SciSpinBox +from ..lib.spinboxes import SciSpinBox from pyqtgraph import PlotWidget diff --git a/nmreval/gui_qt/_py/skipdialog.py b/src/gui_qt/_py/skipdialog.py similarity index 100% rename from nmreval/gui_qt/_py/skipdialog.py rename to src/gui_qt/_py/skipdialog.py diff --git a/nmreval/gui_qt/_py/smoothdialog.py b/src/gui_qt/_py/smoothdialog.py similarity index 100% rename from nmreval/gui_qt/_py/smoothdialog.py rename to src/gui_qt/_py/smoothdialog.py diff --git a/nmreval/gui_qt/_py/t1_calc_dialog.py b/src/gui_qt/_py/t1_calc_dialog.py similarity index 100% rename from nmreval/gui_qt/_py/t1_calc_dialog.py rename to src/gui_qt/_py/t1_calc_dialog.py diff --git a/nmreval/gui_qt/_py/t1_dock.py b/src/gui_qt/_py/t1_dock.py similarity index 100% rename from nmreval/gui_qt/_py/t1_dock.py rename to src/gui_qt/_py/t1_dock.py diff --git a/nmreval/gui_qt/_py/t1_tau_calculation.py b/src/gui_qt/_py/t1_tau_calculation.py similarity index 100% rename from nmreval/gui_qt/_py/t1_tau_calculation.py rename to src/gui_qt/_py/t1_tau_calculation.py diff --git a/nmreval/gui_qt/_py/t1dialog.py b/src/gui_qt/_py/t1dialog.py similarity index 100% rename from nmreval/gui_qt/_py/t1dialog.py rename to src/gui_qt/_py/t1dialog.py diff --git a/nmreval/gui_qt/_py/tntdialog.py b/src/gui_qt/_py/tntdialog.py similarity index 100% rename from nmreval/gui_qt/_py/tntdialog.py rename to src/gui_qt/_py/tntdialog.py diff --git a/nmreval/gui_qt/_py/typeconversion.py b/src/gui_qt/_py/typeconversion.py similarity index 100% rename from nmreval/gui_qt/_py/typeconversion.py rename to src/gui_qt/_py/typeconversion.py diff --git a/nmreval/gui_qt/_py/untitled.py b/src/gui_qt/_py/untitled.py similarity index 100% rename from nmreval/gui_qt/_py/untitled.py rename to src/gui_qt/_py/untitled.py diff --git a/nmreval/gui_qt/_py/userfitassist.py b/src/gui_qt/_py/userfitassist.py similarity index 100% rename from nmreval/gui_qt/_py/userfitassist.py rename to src/gui_qt/_py/userfitassist.py diff --git a/nmreval/gui_qt/_py/usermodeleditor.py b/src/gui_qt/_py/usermodeleditor.py similarity index 100% rename from nmreval/gui_qt/_py/usermodeleditor.py rename to src/gui_qt/_py/usermodeleditor.py diff --git a/nmreval/gui_qt/_py/valueeditor.py b/src/gui_qt/_py/valueeditor.py similarity index 100% rename from nmreval/gui_qt/_py/valueeditor.py rename to src/gui_qt/_py/valueeditor.py diff --git a/nmreval/gui_qt/data/__init__.py b/src/gui_qt/data/__init__.py similarity index 100% rename from nmreval/gui_qt/data/__init__.py rename to src/gui_qt/data/__init__.py diff --git a/nmreval/gui_qt/data/container.py b/src/gui_qt/data/container.py similarity index 98% rename from nmreval/gui_qt/data/container.py rename to src/gui_qt/data/container.py index 285f60e..b1b5b51 100644 --- a/nmreval/gui_qt/data/container.py +++ b/src/gui_qt/data/container.py @@ -1,3 +1,4 @@ +from __future__ import annotations from collections import OrderedDict from itertools import cycle from typing import Any @@ -5,14 +6,14 @@ from typing import Any import numpy as np from pyqtgraph import mkPen -from ...data.points import Points -from ...data.signals import Signal -from ...utils.text import convert -from ...data.bds import BDS -from ...lib.colors import BaseColor, TUColors -from ...lib.lines import LineStyle -from ...lib.symbols import SymbolStyle, symbolcycle -from ...data.nmr import Spectrum, FID +from nmreval.data.points import Points +from nmreval.data.signals import Signal +from nmreval.utils.text import convert +from nmreval.data.bds import BDS +from nmreval.lib.colors import BaseColor, TUColors +from nmreval.lib.lines import LineStyle +from nmreval.lib.symbols import SymbolStyle, symbolcycle +from nmreval.data.nmr import Spectrum, FID from ..Qt import QtCore, QtGui from ..io.exporters import GraceExporter @@ -254,7 +255,7 @@ class ExperimentContainer(QtCore.QObject): def has_fits(self): return len(self._fits) != 0 - def set_fits(self, value: str or list, replace: bool = False): + def set_fits(self, value: str | list, replace: bool = False): if isinstance(value, str): value = [value] diff --git a/nmreval/gui_qt/data/conversion.py b/src/gui_qt/data/conversion.py similarity index 100% rename from nmreval/gui_qt/data/conversion.py rename to src/gui_qt/data/conversion.py diff --git a/nmreval/gui_qt/data/datawidget/__init__.py b/src/gui_qt/data/datawidget/__init__.py similarity index 100% rename from nmreval/gui_qt/data/datawidget/__init__.py rename to src/gui_qt/data/datawidget/__init__.py diff --git a/nmreval/gui_qt/data/datawidget/datawidget.py b/src/gui_qt/data/datawidget/datawidget.py similarity index 99% rename from nmreval/gui_qt/data/datawidget/datawidget.py rename to src/gui_qt/data/datawidget/datawidget.py index 55298ad..09ed6a0 100644 --- a/nmreval/gui_qt/data/datawidget/datawidget.py +++ b/src/gui_qt/data/datawidget/datawidget.py @@ -1,6 +1,7 @@ from typing import List, Tuple, Union from nmreval.lib.colors import available_cycles + from .properties import PropWidget from ...Qt import QtWidgets, QtGui, QtCore from ..._py.datawidget import Ui_DataWidget diff --git a/nmreval/gui_qt/data/datawidget/properties.py b/src/gui_qt/data/datawidget/properties.py similarity index 100% rename from nmreval/gui_qt/data/datawidget/properties.py rename to src/gui_qt/data/datawidget/properties.py diff --git a/nmreval/gui_qt/data/integral_widget.py b/src/gui_qt/data/integral_widget.py similarity index 100% rename from nmreval/gui_qt/data/integral_widget.py rename to src/gui_qt/data/integral_widget.py diff --git a/nmreval/gui_qt/data/interpolate_dialog.py b/src/gui_qt/data/interpolate_dialog.py similarity index 100% rename from nmreval/gui_qt/data/interpolate_dialog.py rename to src/gui_qt/data/interpolate_dialog.py diff --git a/nmreval/gui_qt/data/plot_dialog.py b/src/gui_qt/data/plot_dialog.py similarity index 96% rename from nmreval/gui_qt/data/plot_dialog.py rename to src/gui_qt/data/plot_dialog.py index 9291bcc..3fb878d 100644 --- a/nmreval/gui_qt/data/plot_dialog.py +++ b/src/gui_qt/data/plot_dialog.py @@ -2,9 +2,9 @@ from random import randint import numpy as np -from ... import models -from ...lib.importer import find_models -from ...lib.utils import valid_function +from nmreval import models +from nmreval.lib.importer import find_models +from nmreval.lib.utils import valid_function from ..Qt import QtGui, QtCore, QtWidgets from .._py.setbyfunction_dialog import Ui_NewCurveDialog diff --git a/nmreval/gui_qt/data/point_select.py b/src/gui_qt/data/point_select.py similarity index 100% rename from nmreval/gui_qt/data/point_select.py rename to src/gui_qt/data/point_select.py index c400249..f821ccd 100644 --- a/nmreval/gui_qt/data/point_select.py +++ b/src/gui_qt/data/point_select.py @@ -2,10 +2,10 @@ import re from ..Qt import QtCore, QtWidgets from .._py.ptstab import Ui_Form +from ..lib.pg_objects import LogInfiniteLine, RegionItem __all__ = ['PointSelectWidget'] -from ..lib.pg_objects import LogInfiniteLine, RegionItem REGION_RE = re.compile(r'(?P[+-]*\d+(?:\.\d*)*(?:[eE][+-]*\d+)*)' r'(?: ?- ?(?P[+-]*\d+(?:\.\d*)*(?:[eE][+-]*\d+)*))*') diff --git a/nmreval/gui_qt/data/shift_graphs.py b/src/gui_qt/data/shift_graphs.py similarity index 99% rename from nmreval/gui_qt/data/shift_graphs.py rename to src/gui_qt/data/shift_graphs.py index 3ea8201..fdbd033 100644 --- a/nmreval/gui_qt/data/shift_graphs.py +++ b/src/gui_qt/data/shift_graphs.py @@ -3,7 +3,8 @@ from itertools import cycle from pyqtgraph import mkColor, mkPen -from ...lib.colors import Tab10 +from nmreval.lib.colors import Tab10 + from ..Qt import QtGui, QtCore, QtWidgets from .._py.shift_scale_dialog import Ui_shift_dialog from ..lib.pg_objects import PlotItem diff --git a/nmreval/gui_qt/data/signaledit/__init__.py b/src/gui_qt/data/signaledit/__init__.py similarity index 100% rename from nmreval/gui_qt/data/signaledit/__init__.py rename to src/gui_qt/data/signaledit/__init__.py diff --git a/nmreval/gui_qt/data/signaledit/baseline_dialog.py b/src/gui_qt/data/signaledit/baseline_dialog.py similarity index 94% rename from nmreval/gui_qt/data/signaledit/baseline_dialog.py rename to src/gui_qt/data/signaledit/baseline_dialog.py index c231cd7..79ca27b 100644 --- a/nmreval/gui_qt/data/signaledit/baseline_dialog.py +++ b/src/gui_qt/data/signaledit/baseline_dialog.py @@ -16,14 +16,16 @@ class QBaselineDialog(QtWidgets.QDialog, Ui_SignalEdit): self.data = None - self.graph = pg.PlotDataItem(x=[], y=[], pen=pg.mkPen({'color': 'b'})) - self.graph_corr = pg.PlotDataItem(x=[], y=[], pen=pg.mkPen({'color': 'r'})) - self.baseline = pg.PlotDataItem(x=[], y=[]) + self.graph = pg.PlotDataItem(x=[], y=[], pen=pg.mkPen({'color': 'b'}), name='Original') + self.graph_corr = pg.PlotDataItem(x=[], y=[], pen=pg.mkPen({'color': 'r'}), name='Corrected') + self.baseline = pg.PlotDataItem(x=[], y=[], name='Baseline') self.anchors = [] self.anchor_lines = [] self.spline = None + self.legend = self.graphicsView.addLegend() + self.graphicsView.scene().sigMouseClicked.connect(self.add_node) self.graphicsView.addItem(self.graph_corr) self.graphicsView.addItem(self.graph) diff --git a/nmreval/gui_qt/data/signaledit/editsignalwidget.py b/src/gui_qt/data/signaledit/editsignalwidget.py similarity index 96% rename from nmreval/gui_qt/data/signaledit/editsignalwidget.py rename to src/gui_qt/data/signaledit/editsignalwidget.py index 23bb9cd..1137ce3 100644 --- a/nmreval/gui_qt/data/signaledit/editsignalwidget.py +++ b/src/gui_qt/data/signaledit/editsignalwidget.py @@ -1,6 +1,6 @@ -from ....math import apodization -from ....lib.importer import find_models -from ....utils.text import convert +from src.nmreval.math import apodization +from src.nmreval.lib.importer import find_models +from src.nmreval.utils.text import convert from ...Qt import QtCore, QtWidgets, QtGui from ...lib.forms import FormWidget diff --git a/nmreval/gui_qt/data/signaledit/phase_dialog.py b/src/gui_qt/data/signaledit/phase_dialog.py similarity index 95% rename from nmreval/gui_qt/data/signaledit/phase_dialog.py rename to src/gui_qt/data/signaledit/phase_dialog.py index 6bd670f..ceeb3a7 100644 --- a/nmreval/gui_qt/data/signaledit/phase_dialog.py +++ b/src/gui_qt/data/signaledit/phase_dialog.py @@ -1,12 +1,14 @@ +from __future__ import annotations + import numpy as np from pyqtgraph import mkPen from numpy import inf, linspace from numpy.fft import fft, fftfreq, fftshift from ...lib.pg_objects import PlotItem, LogInfiniteLine -from ....lib.importer import find_models -from ....math import apodization as apodization -from ....utils.text import convert +from nmreval.lib.importer import find_models +from nmreval.math import apodization as apodization +from nmreval.utils.text import convert from ...Qt import QtCore, QtWidgets from ..._py.apod_dialog import Ui_ApodEdit @@ -36,7 +38,7 @@ class QPreviewDialogs(QtWidgets.QDialog): def add_data(self, x, y): self.data.append((x, y)) - real_plt = PlotItem(x=x, y=y.real, pen=mkPen('b')) + real_plt = PlotItem(x=x, y=y.real, pen=mkPen('b'), ) imag_plt = PlotItem(x=x, y=y.imag, pen=mkPen('r')) self.graphs.append((real_plt, imag_plt)) self.graphicsView.addItem(real_plt) @@ -91,7 +93,7 @@ class QPhasedialog(QPreviewDialogs, Ui_SignalEdit): self.pvt_line.setValue(pvt) for i, (x, y) in enumerate(self.data): - phasecorr = np.exp(1j * (ph0 + ph1*(x-pvt)/np.max(x))*np.pi/180.) + phasecorr = np.exp(-1j * (ph0 + ph1*(x-pvt)/np.max(x))*np.pi/180.) _y = y * phasecorr self.graphs[i][0].setData(x=x, y=_y.real) diff --git a/nmreval/gui_qt/data/valueeditwidget.py b/src/gui_qt/data/valueeditwidget.py similarity index 99% rename from nmreval/gui_qt/data/valueeditwidget.py rename to src/gui_qt/data/valueeditwidget.py index fc39a73..4d9f4b2 100644 --- a/nmreval/gui_qt/data/valueeditwidget.py +++ b/src/gui_qt/data/valueeditwidget.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import Any, List +from typing import Any import numpy as np @@ -227,7 +227,7 @@ class ValueModel(QtCore.QAbstractTableModel): def columnCount(self, *args, **kwargs) -> int: return len(self.headers) - def loadData(self, data: List[np.ndarray], mask: np.ndarray): + def loadData(self, data: list[np.ndarray], mask: np.ndarray): self.beginResetModel() self._data = [] for x, y, y_err in zip(*data): diff --git a/nmreval/gui_qt/fit/__init__.py b/src/gui_qt/fit/__init__.py similarity index 100% rename from nmreval/gui_qt/fit/__init__.py rename to src/gui_qt/fit/__init__.py diff --git a/nmreval/gui_qt/fit/fit_forms.py b/src/gui_qt/fit/fit_forms.py similarity index 98% rename from nmreval/gui_qt/fit/fit_forms.py rename to src/gui_qt/fit/fit_forms.py index 354d02d..fe33211 100644 --- a/nmreval/gui_qt/fit/fit_forms.py +++ b/src/gui_qt/fit/fit_forms.py @@ -1,8 +1,7 @@ from __future__ import annotations -from typing import List, Tuple, Union +from nmreval.utils.text import convert -from ...utils.text import convert from ..Qt import QtCore, QtWidgets, QtGui from .._py.fitmodelwidget import Ui_FitParameter from .._py.save_fitmodel_dialog import Ui_SaveDialog @@ -68,7 +67,7 @@ class FitModelWidget(QtWidgets.QWidget, Ui_FitParameter): self.lineEdit.setEnabled(value == 2) self.lineEdit_2.setEnabled(value == 2) - def set_parameter(self, p: float | None, bds: Tuple[float, float, bool] = None, + def set_parameter(self, p: float | None, bds: tuple[float, float, bool] = None, fixed: bool = None, glob: bool = None): if p is None: # bad hack: linked parameter return (None, linked parameter) @@ -281,7 +280,7 @@ class FitModelTree(QtWidgets.QTreeWidget): idx = item.data(0, self.counterRole) self.itemRemoved.emit(idx) - def add_function(self, idx: int, cnt: int, op: int, name: str, color: Union[QtGui.QColor, str, tuple], + def add_function(self, idx: int, cnt: int, op: int, name: str, color: QtGui.QColor | str | tuple, parent: QtWidgets.QTreeWidgetItem = None, children: list = None, active: bool = True, **kwargs): """ Add function to tree and dictionary of functions. @@ -403,7 +402,7 @@ class FitTableWidget(QtWidgets.QTableWidget): self.hideColumn(1) self.resizeColumnToContents(0) - def load(self, set_ids: List[str]): + def load(self, set_ids: list[str]): self.blockSignals(True) while self.rowCount(): diff --git a/nmreval/gui_qt/fit/fit_parameter.py b/src/gui_qt/fit/fit_parameter.py similarity index 99% rename from nmreval/gui_qt/fit/fit_parameter.py rename to src/gui_qt/fit/fit_parameter.py index f2d4111..1027519 100644 --- a/nmreval/gui_qt/fit/fit_parameter.py +++ b/src/gui_qt/fit/fit_parameter.py @@ -1,6 +1,7 @@ from __future__ import annotations -from ...utils.text import convert +from nmreval.utils.text import convert + from ..Qt import QtWidgets, QtCore, QtGui from .._py.fitfuncwidget import Ui_FormFit from ..lib.forms import SelectionWidget diff --git a/nmreval/gui_qt/fit/fitfunction.py b/src/gui_qt/fit/fitfunction.py similarity index 94% rename from nmreval/gui_qt/fit/fitfunction.py rename to src/gui_qt/fit/fitfunction.py index 0d98c4b..9eab41f 100644 --- a/nmreval/gui_qt/fit/fitfunction.py +++ b/src/gui_qt/fit/fitfunction.py @@ -1,15 +1,16 @@ +from __future__ import annotations + from itertools import cycle, count -from typing import List, Tuple, Union + +from nmreval.configs import config_paths +from nmreval import models +from nmreval.lib.importer import find_models +from nmreval.lib.colors import BaseColor, Tab10 +from nmreval.utils.text import convert from ..lib import get_icon from .._py.fitfunctionwidget import Ui_Form from ..Qt import QtWidgets, QtCore, QtGui -from ...configs import config_paths -from ... import models -from ...lib.importer import find_models -from ...lib.colors import BaseColor, Tab10 -from ...utils.text import convert - class QFunctionWidget(QtWidgets.QWidget, Ui_Form): func_cnt = count() @@ -104,7 +105,7 @@ class QFunctionWidget(QtWidgets.QWidget, Ui_Form): self.add_function(idx, cnt, op, name, col) def add_function(self, idx: int, cnt: int, op: int, - name: str, color: Union[str, Tuple[float, float, float], BaseColor], **kwargs): + name: str, color: str | tuple[float, float, float] | BaseColor, **kwargs): """ Add function to tree and dictionary of functions. """ @@ -160,7 +161,7 @@ class QFunctionWidget(QtWidgets.QWidget, Ui_Form): return used_functions - def _prepare_function_for_model(self, func_list: List[dict], + def _prepare_function_for_model(self, func_list: list[dict], full: bool = True, clsname: bool = False, include_all: bool = True): for func_args in func_list: diff --git a/nmreval/gui_qt/fit/fitwindow.py b/src/gui_qt/fit/fitwindow.py similarity index 99% rename from nmreval/gui_qt/fit/fitwindow.py rename to src/gui_qt/fit/fitwindow.py index 99abc5f..173d6e6 100644 --- a/nmreval/gui_qt/fit/fitwindow.py +++ b/src/gui_qt/fit/fitwindow.py @@ -9,13 +9,14 @@ from typing import Dict, List, Tuple import numpy as np from pyqtgraph import mkPen +from nmreval.fit._meta import MultiModel, ModelFactory +from nmreval.fit.result import FitResult + from .fit_forms import FitTableWidget from .fit_parameter import QFitParameterWidget from ..lib.pg_objects import PlotItem from ..Qt import QtGui, QtCore, QtWidgets from .._py.fitdialog import Ui_FitDialog -from ...fit._meta import MultiModel, ModelFactory -from ...fit.result import FitResult class QFitDialog(QtWidgets.QWidget, Ui_FitDialog): diff --git a/src/gui_qt/fit/function_creation_dialog.py b/src/gui_qt/fit/function_creation_dialog.py new file mode 100644 index 0000000..8d6c2a0 --- /dev/null +++ b/src/gui_qt/fit/function_creation_dialog.py @@ -0,0 +1,449 @@ +from __future__ import annotations + +import inspect +import numbers +import textwrap +from typing import Any + +import numpy as np + +from gui_qt.Qt import QtCore, QtWidgets, QtGui +from gui_qt._py.fitcreationdialog import Ui_Dialog +from gui_qt.lib.namespace import QNamespaceWidget + +__all__ = ['QUserFitCreator'] + +validator = QtGui.QRegExpValidator(QtCore.QRegExp('[A-Za-z]\S*')) + + +class QUserFitCreator(QtWidgets.QDialog, Ui_Dialog): + classCreated = QtCore.pyqtSignal(object) + + def __init__(self, parent=None): + super().__init__(parent=parent) + self.setupUi(self) + + self.description_widget = DescWidget(self) + self.args_widget = ArgWidget(self) + self.kwargs_widget = KwargsWidget(self) + self.kwargs_widget.Changed.connect(self.update_function) + self.namespace_widget = QNamespaceWidget(self) + self.namespace_widget.make_namespace() + self.namespace_widget.sendKey.connect(self.namespace_made) + + for b, w in [(self.description_box, self.description_widget), (self.args_box, self.args_widget), + (self.kwargs_box, self.kwargs_widget), (self.namespace_box, self.namespace_widget)]: + b.layout().addWidget(w) + try: + w.Changed.connect(self.update_function) + except AttributeError: + pass + b.layout().addStretch() + + self._imports = set() + + self.update_function() + + def __call__(self, *args, **kwargs): + return self + + def update_function(self): + try: + var = self.args_widget.get_parameter() + var += self.kwargs_widget.get_parameter() + + k = '' + for imps in self._imports: + if len(imps) == 2: + k += f'from {imps[0]} import {imps[1]}\n' + elif imps[0] == 'numpy': + k += 'import numpy as np\n' + + if len(self._imports): + k += '\n\n' + + k += self.description_widget.get_strings() + k += self.args_widget.get_strings() + k += self.kwargs_widget.get_strings() + + k += '\n @staticmethod\n' + k += f" def func(x, {', '.join(var)}):\n" + + self.plainTextEdit.setPlainText(k) + except Exception as e: + QtWidgets.QMessageBox.warning(self, 'Failure', f'Error found: {e.args[0]}') + + def change_visibility(self): + sender = self.sender() + + for box in (self.description_box, self.args_box, self.kwargs_box, self.namespace_box): + box.blockSignals(True) + box.setExpansion(sender == box) + box.blockSignals(False) + + def namespace_made(self, invalue: str): + ns = self.namespace_widget.namespace.namespace + func_value = ns[invalue][0] + ret_func = '' + + if func_value is None: + ret_func = invalue + + elif isinstance(func_value, numbers.Number): + ret_func = func_value + + elif isinstance(func_value, np.ufunc): + self._imports.add(('numpy',)) + ret_func = 'np.'+func_value.__name__ + '(x)' + + else: + f_string = ns[invalue][-1] + args = f_string[f_string.find('('):] + if inspect.ismethod(func_value): + ret_func = func_value.__self__.__name__ + '.func'+args + elif hasattr(func_value, '__qualname__'): + ret_func = func_value.__qualname__.split('.')[0] + self._imports.add((inspect.getmodule(func_value).__name__, ret_func)) + + self.plainTextEdit.insertPlainText(ret_func) + self.update_function() + + +class KwargsWidget(QtWidgets.QWidget): + Changed = QtCore.pyqtSignal() + + def __init__(self, parent=None): + super().__init__(parent=parent) + self._num_kwargs = 0 + + self._setup_ui() + + def _setup_ui(self): + layout = QtWidgets.QGridLayout() + layout.setContentsMargins(3, 3, 3, 3) + layout.setHorizontalSpacing(3) + + self.use_nuclei = QtWidgets.QCheckBox('Add gyromagnetic ratio', self) + self.use_nuclei.stateChanged.connect(lambda x: self.Changed.emit()) + layout.addWidget(self.use_nuclei, 0, 0, 1, 3) + + self.choices = QtWidgets.QTabWidget(self) + layout.addWidget(self.choices, 1, 0, 1, 3) + + self.add_choice_button = QtWidgets.QPushButton('Add choice', self) + self.add_choice_button.clicked.connect(self.add_choice) + layout.addWidget(self.add_choice_button, 2, 0, 1, 1) + + self.rem_choice_button = QtWidgets.QPushButton('Remove choice', self) + self.rem_choice_button.clicked.connect(self.remove_choice) + layout.addWidget(self.rem_choice_button, 2, 1, 1, 1) + + self.setLayout(layout) + + def add_choice(self): + cnt = self._num_kwargs + c = ChoiceWidget(cnt, self) + c.Changed.connect(self.update_choice) + self.choices.addTab(c, c.name_line.text()) + + self._num_kwargs += 1 + + self.choices.setCurrentIndex(cnt) + self.Changed.emit() + + def remove_choice(self): + cnt = self.choices.currentIndex() + self.choices.removeTab(cnt) + self.Changed.emit() + + def update_choice(self): + idx = self.choices.currentIndex() + self.choices.setTabText(idx, self.sender().name_line.text()) + self.Changed.emit() + + def get_parameter(self): + if self.use_nuclei.isChecked(): + var = ['nucleus=2.67522128e7'] + else: + var = [] + var += [self.choices.widget(idx).get_parameter() for idx in range(self.choices.count())] + + return var + + def get_strings(self) -> str: + kwargs = [] + if self.use_nuclei.isChecked(): + kwargs.append("(r'\gamma', 'nucleus', gamma)") + + for i in range(self.choices.count()): + kwargs.append(self.choices.widget(i).get_strings()) + if kwargs: + return f" choices = {', '.join(kwargs)}\n" + else: + return '' + + +class ChoiceWidget(QtWidgets.QWidget): + Changed = QtCore.pyqtSignal() + + def __init__(self, idx: int, parent=None): + super().__init__(parent=parent) + + self._setup_ui() + + self.name_line.setText('choice' + str(idx)) + self.add_option() + + def _setup_ui(self): + layout = QtWidgets.QGridLayout() + layout.setContentsMargins(3, 3, 3, 3) + layout.setHorizontalSpacing(3) + + self.name_label = QtWidgets.QLabel('Name', self) + layout.addWidget(self.name_label, 0, 0, 1, 1) + self.name_line = QtWidgets.QLineEdit(self) + self.name_line.textChanged.connect(lambda x: self.Changed.emit()) + layout.addWidget(self.name_line, 0, 1, 1, 1) + + self.disp_label = QtWidgets.QLabel('Disp. name', self) + layout.addWidget(self.disp_label, 1, 0, 1, 1) + self.display_line = QtWidgets.QLineEdit(self) + self.display_line.textChanged.connect(lambda x: self.Changed.emit()) + layout.addWidget(self.display_line, 1, 1, 1, 1) + + self.add_button = QtWidgets.QPushButton('Add option', self) + self.add_button.clicked.connect(self.add_option) + layout.addWidget(self.add_button, 2, 0, 1, 2) + + self.remove_button = QtWidgets.QPushButton('Remove option', self) + self.remove_button.clicked.connect(self.remove_option) + layout.addWidget(self.remove_button, 3, 0, 1, 2) + + self.table = QtWidgets.QTableWidget(self) + self.table.setColumnCount(3) + self.table.setHorizontalHeaderLabels(['Name', 'Value', 'Type']) + self.table.itemChanged.connect(lambda x: self.Changed.emit()) + layout.addWidget(self.table, 0, 2, 4, 1) + + self.setLayout(layout) + + def add_option(self): + self.table.blockSignals(True) + row = self.table.rowCount() + self.table.setRowCount(row+1) + + self.table.setItem(row, 0, QtWidgets.QTableWidgetItem('opt' + str(row))) + lineedit = QtWidgets.QLineEdit() + lineedit.setValidator(validator) + lineedit.setFrame(False) + lineedit.setText('opt'+str(row)) + lineedit.textChanged.connect(lambda x: self.Changed.emit()) + self.table.setCellWidget(row, 0, lineedit) + self.table.setItem(row, 1, QtWidgets.QTableWidgetItem('None')) + + self.table.setItem(row, 2, QtWidgets.QTableWidgetItem('')) + cb = QtWidgets.QComboBox() + cb.addItems(['None', 'str', 'float', 'int', 'bool']) + cb.currentIndexChanged.connect(lambda x: self.Changed.emit()) + self.table.setCellWidget(row, 2, cb) + + self.table.blockSignals(False) + + self.Changed.emit() + + def remove_option(self): + if self.table.rowCount() > 1: + self.table.blockSignals(True) + self.table.removeRow(self.table.currentRow()) + self.table.blockSignals(False) + self.Changed.emit() + + def get_parameter(self) -> str: + return f'{self.name_line.text()}={self._make_value(0)!r}' + + def get_strings(self) -> str: + opts = [] + for i in range(self.table.rowCount()): + name = self.table.item(i, 0).text() + val = self._make_value(i) + opts.append(f'{name!r}: {val!r}') + + opts = f"{{{', '.join(opts)}}}" + + disp = self.display_line.text() + name = self.name_line.text() + if disp == '': + ret_val = '(' + ', '.join([repr(name), repr(name), opts]) + ')' + else: + ret_val = '(' + ', '.join([repr(name), repr(disp), opts]) + ')' + + return ret_val + + def _make_value(self, i) -> Any: + dtype = self.table.cellWidget(i, 2).currentIndex() + val = self.table.item(i, 1).text() + cast = [None, str, float, int, bool] + if dtype == 0: + val = None + else: + try: + val = cast[dtype](val) + except: + raise ValueError(f'Invalid argument for {self.table.cellWidget(i, 0).text()}') + + return val + + +class ArgWidget(QtWidgets.QWidget): + Changed = QtCore.pyqtSignal() + + def __init__(self, parent=None): + super().__init__(parent=parent) + + self._setup_ui() + + def _setup_ui(self): + layout = QtWidgets.QGridLayout() + layout.setContentsMargins(3, 3, 3, 3) + layout.setHorizontalSpacing(3) + + self.table = QtWidgets.QTableWidget(self) + self.table.setColumnCount(4) + self.table.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) + self.table.setRowCount(0) + self.table.setHorizontalHeaderLabels(['Variable', 'Disp. name', 'Lower bound', 'Upper bound']) + self.table.itemChanged.connect(lambda x: self.Changed.emit()) + layout.addWidget(self.table, 0, 0, 1, 3) + + self.add_button = QtWidgets.QPushButton('Add parameter', self) + self.add_button.clicked.connect(self.add_variable) + layout.addWidget(self.add_button, 1, 0, 1, 1) + + self.rem_button = QtWidgets.QPushButton('Remove parameter', self) + self.rem_button.clicked.connect(self.remove_variable) + layout.addWidget(self.rem_button, 1, 1, 1, 1) + + spacer = QtWidgets.QSpacerItem(0, 0) + layout.addItem(spacer, 1, 2, 1, 1) + + self.setLayout(layout) + + def add_variable(self): + self.table.blockSignals(True) + row = self.table.rowCount() + self.table.setRowCount(row + 1) + + self.table.setItem(row, 0, QtWidgets.QTableWidgetItem('p' + str(row))) + # arguments cannot start with a number or have spaces + lineedit = QtWidgets.QLineEdit() + lineedit.setValidator(validator) + lineedit.setFrame(False) + lineedit.setText('p'+str(row)) + lineedit.textChanged.connect(lambda x: self.Changed.emit()) + self.table.setCellWidget(row, 0, lineedit) + + self.table.setItem(row, 1, QtWidgets.QTableWidgetItem('p_{' + str(row) + '}')) + self.table.setItem(row, 2, QtWidgets.QTableWidgetItem('--')) + self.table.setItem(row, 3, QtWidgets.QTableWidgetItem('--')) + self.table.blockSignals(False) + + self.Changed.emit() + + def remove_variable(self): + self.table.blockSignals(True) + self.table.removeRow(self.table.currentRow()) + self.table.blockSignals(False) + + self.Changed.emit() + + def get_parameter(self) -> list[str]: + var = [] + for row in range(self.table.rowCount()): + var.append(self.table.cellWidget(row, 0).text()) + + return var + + def get_strings(self): + args = [] + bnds = [] + for row in range(self.table.rowCount()): + args.append(self.table.item(row, 1).text()) + lb = self.table.item(row, 2).text() + lb = None if lb in ['--', 'None'] else float(lb) + + ub = self.table.item(row, 3).text() + ub = None if ub in ['--', 'None'] else float(ub) + + if ub is not None and lb is not None: + if not (lb < ub): + raise ValueError('Some bounds are invalid') + + bnds.append(f'({lb}, {ub})') + + stringi = f' params = {args}\n' + stringi += f" bounds = [{', '.join(bnds)}]\n" + + return stringi + + +class DescWidget(QtWidgets.QWidget): + Changed = QtCore.pyqtSignal() + + def __init__(self, parent=None): + super().__init__(parent=parent) + + self._setup_ui() + + def _setup_ui(self): + layout = QtWidgets.QGridLayout() + layout.setContentsMargins(3, 3, 3, 3) + layout.setSpacing(3) + + self.klass_label = QtWidgets.QLabel('Class', self) + layout.addWidget(self.klass_label, 0, 0, 1, 1) + self.klass_lineedit = QtWidgets.QLineEdit(self) + self.klass_lineedit.setValidator(validator) + self.klass_lineedit.setText('UserClass') + self.klass_lineedit.textChanged.connect(lambda x: self.Changed.emit()) + layout.addWidget(self.klass_lineedit, 0, 1, 1, 1) + + self.name_label = QtWidgets.QLabel('Name', self) + layout.addWidget(self.name_label, 1, 0, 1, 1) + self.name_lineedit = QtWidgets.QLineEdit(self) + self.name_lineedit.setText('Name of function') + self.name_lineedit.textChanged.connect(lambda x: self.Changed.emit()) + layout.addWidget(self.name_lineedit, 1, 1, 1, 1) + + self.group_label = QtWidgets.QLabel('Group', self) + layout.addWidget(self.group_label, 2, 0, 1, 1) + self.group_lineedit = QtWidgets.QLineEdit(self) + self.group_lineedit.setText('User-defined') + self.group_lineedit.textChanged.connect(lambda x: self.Changed.emit()) + layout.addWidget(self.group_lineedit, 2, 1, 1, 1) + + self.eq_label = QtWidgets.QLabel('Disp. equation', self) + layout.addWidget(self.eq_label, 3, 0, 1, 1) + self.eq_lineedit = QtWidgets.QLineEdit(self) + self.eq_lineedit.textChanged.connect(lambda x: self.Changed.emit()) + layout.addWidget(self.eq_lineedit, 3, 1, 1, 1) + + self.setLayout(layout) + + def get_strings(self) -> str: + if self.klass_lineedit.text() == '': + raise ValueError('Class name is empty') + stringi = f'class {self.klass_lineedit.text()}:\n' \ + f' name = {self.name_lineedit.text()!r}\n' \ + f' group = {self.group_lineedit.text()!r}\n' \ + f' equation = {self.eq_lineedit.text()!r}\n' + + return stringi + + +if __name__ == '__main__': + import sys + app = QtWidgets.QApplication([]) + win = QUserFitCreator() + win.show() + + sys.exit(app.exec()) diff --git a/nmreval/gui_qt/fit/result.py b/src/gui_qt/fit/result.py similarity index 99% rename from nmreval/gui_qt/fit/result.py rename to src/gui_qt/fit/result.py index fc13198..9fd24a4 100644 --- a/nmreval/gui_qt/fit/result.py +++ b/src/gui_qt/fit/result.py @@ -1,10 +1,10 @@ from math import isnan -from numpy import r_ from pyqtgraph import mkBrush +from nmreval.utils.text import convert + from ..lib.utils import RdBuCMap -from ...utils.text import convert from ..Qt import QtWidgets, QtGui, QtCore from .._py.fitresult import Ui_Dialog from ..lib.pg_objects import PlotItem diff --git a/nmreval/gui_qt/graphs/__init__.py b/src/gui_qt/graphs/__init__.py similarity index 100% rename from nmreval/gui_qt/graphs/__init__.py rename to src/gui_qt/graphs/__init__.py diff --git a/nmreval/gui_qt/graphs/graphwindow.py b/src/gui_qt/graphs/graphwindow.py similarity index 99% rename from nmreval/gui_qt/graphs/graphwindow.py rename to src/gui_qt/graphs/graphwindow.py index 0004b93..64ab6f3 100644 --- a/nmreval/gui_qt/graphs/graphwindow.py +++ b/src/gui_qt/graphs/graphwindow.py @@ -1,15 +1,17 @@ +from __future__ import annotations + import itertools import os import uuid from math import isnan -from typing import List, Union from numpy import errstate, floor, log10 from pyqtgraph import GraphicsObject, getConfigOption, mkColor +from nmreval.utils.text import convert + from ..lib.pg_objects import LegendItemBlock, RegionItem -from ...utils.text import convert from ..Qt import QtCore, QtWidgets, QtGui from .._py.graph import Ui_GraphWindow from ..lib import make_action_icons @@ -127,7 +129,7 @@ class QGraphWindow(QtWidgets.QGraphicsView, Ui_GraphWindow): self.setWindowTitle(str(value)) @property - def ranges(self): + def ranges(self) -> tuple: r = self.plotItem.getViewBox().viewRange() for i in [0, 1]: if self.log[i]: @@ -137,7 +139,7 @@ class QGraphWindow(QtWidgets.QGraphicsView, Ui_GraphWindow): return tuple(r) - def add(self, name: Union[str, List], plots: List): + def add(self, name: str | list, plots: list): if isinstance(name, str): name = [name] plots = [plots] @@ -165,7 +167,7 @@ class QGraphWindow(QtWidgets.QGraphicsView, Ui_GraphWindow): self.show_item(name) - def remove(self, name: Union[str, List]): + def remove(self, name: str | list): if isinstance(name, str): name = [name] @@ -191,7 +193,7 @@ class QGraphWindow(QtWidgets.QGraphicsView, Ui_GraphWindow): self._update_zorder() self.show_legend() - def move_sets(self, sets, position): + def move_sets(self, sets: list, position: int): move_plots = [] move_items = [] diff --git a/nmreval/gui_qt/graphs/guide_lines.py b/src/gui_qt/graphs/guide_lines.py similarity index 100% rename from nmreval/gui_qt/graphs/guide_lines.py rename to src/gui_qt/graphs/guide_lines.py diff --git a/nmreval/gui_qt/graphs/movedialog.py b/src/gui_qt/graphs/movedialog.py similarity index 100% rename from nmreval/gui_qt/graphs/movedialog.py rename to src/gui_qt/graphs/movedialog.py diff --git a/nmreval/gui_qt/io/__init__.py b/src/gui_qt/io/__init__.py similarity index 100% rename from nmreval/gui_qt/io/__init__.py rename to src/gui_qt/io/__init__.py diff --git a/nmreval/gui_qt/io/asciireader.py b/src/gui_qt/io/asciireader.py similarity index 99% rename from nmreval/gui_qt/io/asciireader.py rename to src/gui_qt/io/asciireader.py index 43a6a9f..f609407 100644 --- a/nmreval/gui_qt/io/asciireader.py +++ b/src/gui_qt/io/asciireader.py @@ -1,4 +1,4 @@ -from ...io.asciireader import AsciiReader +from nmreval.io.asciireader import AsciiReader from ..Qt import QtGui, QtCore, QtWidgets from .._py.asciidialog import Ui_ascii_reader diff --git a/nmreval/gui_qt/io/bdsreader.py b/src/gui_qt/io/bdsreader.py similarity index 98% rename from nmreval/gui_qt/io/bdsreader.py rename to src/gui_qt/io/bdsreader.py index 5f3af5a..dc52c4c 100644 --- a/nmreval/gui_qt/io/bdsreader.py +++ b/src/gui_qt/io/bdsreader.py @@ -1,4 +1,4 @@ -from ...io.bds_reader import BDSReader +from nmreval.io.bds_reader import BDSReader from ..Qt import QtCore, QtWidgets from .._py.bdsdialog import Ui_Dialog diff --git a/nmreval/gui_qt/io/dscreader.py b/src/gui_qt/io/dscreader.py similarity index 98% rename from nmreval/gui_qt/io/dscreader.py rename to src/gui_qt/io/dscreader.py index c272cfe..33f7938 100644 --- a/nmreval/gui_qt/io/dscreader.py +++ b/src/gui_qt/io/dscreader.py @@ -5,10 +5,11 @@ from pathlib import Path import numpy as np from pyqtgraph import PlotDataItem +from nmreval.data.points import Points +from nmreval.io.dsc import Cyclohexane, DSCCalibrator, DSCSample + from ..Qt import QtWidgets, QtCore from .._py.dscfile_dialog import Ui_Dialog -from ...data.points import Points -from ...io.dsc import Cyclohexane, DSCCalibrator, DSCSample class QDSCReader(QtWidgets.QDialog, Ui_Dialog): diff --git a/nmreval/gui_qt/io/exporters.py b/src/gui_qt/io/exporters.py similarity index 97% rename from nmreval/gui_qt/io/exporters.py rename to src/gui_qt/io/exporters.py index 8dec1ed..363fdd5 100644 --- a/nmreval/gui_qt/io/exporters.py +++ b/src/gui_qt/io/exporters.py @@ -2,8 +2,8 @@ from __future__ import annotations from numpy import c_ -from ...io.graceeditor import GraceEditor -from ...utils.text import convert +from nmreval.io.graceeditor import GraceEditor +from nmreval.utils.text import convert from ..Qt import QtGui, QtCore, QtPrintSupport diff --git a/nmreval/gui_qt/io/fcbatchreader.py b/src/gui_qt/io/fcbatchreader.py similarity index 96% rename from nmreval/gui_qt/io/fcbatchreader.py rename to src/gui_qt/io/fcbatchreader.py index 40bf518..0cffdd2 100644 --- a/nmreval/gui_qt/io/fcbatchreader.py +++ b/src/gui_qt/io/fcbatchreader.py @@ -1,6 +1,7 @@ import pathlib -from ...io.fcbatchreader import FCReader +from nmreval.io.fcbatchreader import FCReader + from ..lib.utils import busy_cursor from ..Qt import QtCore, QtWidgets, QtGui from .._py.fcreader import Ui_FCEval_dialog @@ -86,8 +87,7 @@ class QFCReader(QtWidgets.QDialog, Ui_FCEval_dialog): try: fc_eval.load_magnetization(region=region, overwrite=self.overwrite_cb.isChecked()) except OSError as e: - QtWidgets.QMessageBox.warning(self, 'Mssing data', e.strerror) - self.statelabel.setText('') + QtWidgets.QMessageBox.warning(self, 'Missing data', e.strerror) return fc_eval.fit(kww=self.kww_checkbox.isChecked(), save_fits=True, save_fig=True) diff --git a/nmreval/gui_qt/io/filedialog.py b/src/gui_qt/io/filedialog.py similarity index 100% rename from nmreval/gui_qt/io/filedialog.py rename to src/gui_qt/io/filedialog.py diff --git a/nmreval/gui_qt/io/filereaders.py b/src/gui_qt/io/filereaders.py similarity index 95% rename from nmreval/gui_qt/io/filereaders.py rename to src/gui_qt/io/filereaders.py index b2c3db5..54cacb1 100755 --- a/nmreval/gui_qt/io/filereaders.py +++ b/src/gui_qt/io/filereaders.py @@ -1,9 +1,9 @@ +from __future__ import annotations + from pathlib import Path import struct -from typing import List, Union from ..Qt import QtCore - from .asciireader import QAsciiReader from .hdfreader import QHdfViewer from .bdsreader import QBDSReader @@ -31,7 +31,7 @@ class QFileReader(QtCore.QObject): ]: self.register(ext, reader) - def __call__(self, files: Union[List[str], str]) -> List: + def __call__(self, files: list[str] | str) -> list: self.data = [] if isinstance(files, str): self.filenames = [files] @@ -40,7 +40,7 @@ class QFileReader(QtCore.QObject): return self.readfiles(files) - def readfiles(self, fname: Union[List[str], str]) -> List: + def readfiles(self, fname: list[str] | str) -> list: if not isinstance(fname, list): fname = [fname] diff --git a/nmreval/gui_qt/io/gracereader.py b/src/gui_qt/io/gracereader.py similarity index 95% rename from nmreval/gui_qt/io/gracereader.py rename to src/gui_qt/io/gracereader.py index 57435f2..9196e61 100644 --- a/nmreval/gui_qt/io/gracereader.py +++ b/src/gui_qt/io/gracereader.py @@ -1,7 +1,7 @@ -from ...lib.lines import LineStyle -from ...lib.symbols import SymbolStyle -from ...data.points import Points -from ...io.graceeditor import GraceEditor +from nmreval.lib.lines import LineStyle +from nmreval.lib.symbols import SymbolStyle +from nmreval.data.points import Points +from nmreval.io.graceeditor import GraceEditor from ..Qt import QtCore, QtWidgets, QtGui from .._py.gracereader import Ui_Dialog diff --git a/nmreval/gui_qt/io/hdfreader.py b/src/gui_qt/io/hdfreader.py similarity index 99% rename from nmreval/gui_qt/io/hdfreader.py rename to src/gui_qt/io/hdfreader.py index d272413..c59ad01 100644 --- a/nmreval/gui_qt/io/hdfreader.py +++ b/src/gui_qt/io/hdfreader.py @@ -1,4 +1,4 @@ -from ...io.hdfreader import HdfReader +from nmreval.io.hdfreader import HdfReader from ..Qt import QtGui, QtCore, QtWidgets from .._py.hdftree import Ui_Hdf_Dialog diff --git a/nmreval/gui_qt/io/nmrreader.py b/src/gui_qt/io/nmrreader.py similarity index 95% rename from nmreval/gui_qt/io/nmrreader.py rename to src/gui_qt/io/nmrreader.py index 6e2a374..95614f3 100644 --- a/nmreval/gui_qt/io/nmrreader.py +++ b/src/gui_qt/io/nmrreader.py @@ -1,6 +1,6 @@ from struct import unpack -from ...io.nmrreader import NMRReader +from nmreval.io.nmrreader import NMRReader from ..Qt import QtCore diff --git a/nmreval/gui_qt/io/save_fitparameter.py b/src/gui_qt/io/save_fitparameter.py similarity index 100% rename from nmreval/gui_qt/io/save_fitparameter.py rename to src/gui_qt/io/save_fitparameter.py diff --git a/nmreval/gui_qt/io/tntreader.py b/src/gui_qt/io/tntreader.py similarity index 98% rename from nmreval/gui_qt/io/tntreader.py rename to src/gui_qt/io/tntreader.py index cd97c76..f094518 100644 --- a/nmreval/gui_qt/io/tntreader.py +++ b/src/gui_qt/io/tntreader.py @@ -1,4 +1,4 @@ -from ...io.tntreader import TNTReader +from nmreval.io.tntreader import TNTReader from ..Qt import QtCore, QtWidgets from .._py.tntdialog import Ui_tntdialog diff --git a/nmreval/gui_qt/lib/__init__.py b/src/gui_qt/lib/__init__.py similarity index 100% rename from nmreval/gui_qt/lib/__init__.py rename to src/gui_qt/lib/__init__.py diff --git a/nmreval/gui_qt/lib/codeeditor.py b/src/gui_qt/lib/codeeditor.py similarity index 100% rename from nmreval/gui_qt/lib/codeeditor.py rename to src/gui_qt/lib/codeeditor.py diff --git a/nmreval/gui_qt/lib/color_dialog.py b/src/gui_qt/lib/color_dialog.py similarity index 96% rename from nmreval/gui_qt/lib/color_dialog.py rename to src/gui_qt/lib/color_dialog.py index f9a5601..538938a 100644 --- a/nmreval/gui_qt/lib/color_dialog.py +++ b/src/gui_qt/lib/color_dialog.py @@ -1,7 +1,8 @@ -from ...configs import config_paths +from nmreval.configs import config_paths +from nmreval.lib.colors import Colors, available_cycles + from ..Qt import QtWidgets, QtCore, QtGui from .._py.color_palette import Ui_Dialog -from ...lib.colors import Colors, available_cycles class ColorDialog(QtWidgets.QDialog, Ui_Dialog): diff --git a/nmreval/gui_qt/lib/configurations.py b/src/gui_qt/lib/configurations.py similarity index 98% rename from nmreval/gui_qt/lib/configurations.py rename to src/gui_qt/lib/configurations.py index 0bc114f..c92f065 100644 --- a/nmreval/gui_qt/lib/configurations.py +++ b/src/gui_qt/lib/configurations.py @@ -1,7 +1,7 @@ import os -from ...configs import * -from ...io.graceeditor import GraceEditor +from nmreval.configs import * +from nmreval.io.graceeditor import GraceEditor from ..Qt import QtWidgets, QtGui from .._py.agroptiondialog import Ui_Dialog diff --git a/nmreval/gui_qt/lib/decorators.py b/src/gui_qt/lib/decorators.py similarity index 100% rename from nmreval/gui_qt/lib/decorators.py rename to src/gui_qt/lib/decorators.py diff --git a/nmreval/gui_qt/lib/delegates.py b/src/gui_qt/lib/delegates.py similarity index 98% rename from nmreval/gui_qt/lib/delegates.py rename to src/gui_qt/lib/delegates.py index d26c1f0..bbad0b7 100644 --- a/nmreval/gui_qt/lib/delegates.py +++ b/src/gui_qt/lib/delegates.py @@ -1,10 +1,10 @@ import re -from ..Qt import QtWidgets, QtGui, QtCore +from nmreval.lib.colors import BaseColor, Colors +from nmreval.lib.lines import LineStyle +from nmreval.lib.symbols import SymbolStyle, make_symbol_pixmap -from ...lib.colors import BaseColor, Colors -from ...lib.lines import LineStyle -from ...lib.symbols import SymbolStyle, make_symbol_pixmap +from ..Qt import QtWidgets, QtGui, QtCore class PropertyDelegate(QtWidgets.QStyledItemDelegate): diff --git a/nmreval/gui_qt/lib/expandablewidget.py b/src/gui_qt/lib/expandablewidget.py similarity index 100% rename from nmreval/gui_qt/lib/expandablewidget.py rename to src/gui_qt/lib/expandablewidget.py diff --git a/nmreval/gui_qt/lib/forms.py b/src/gui_qt/lib/forms.py similarity index 99% rename from nmreval/gui_qt/lib/forms.py rename to src/gui_qt/lib/forms.py index f42bc00..6a51c3a 100644 --- a/nmreval/gui_qt/lib/forms.py +++ b/src/gui_qt/lib/forms.py @@ -1,6 +1,6 @@ from numpy import inf -from ...utils.text import convert +from nmreval.utils.text import convert from ..Qt import QtGui, QtCore, QtWidgets from .._py.mean_form import Ui_mean_form diff --git a/nmreval/gui_qt/lib/gol.py b/src/gui_qt/lib/gol.py similarity index 100% rename from nmreval/gui_qt/lib/gol.py rename to src/gui_qt/lib/gol.py diff --git a/nmreval/gui_qt/lib/namespace.py b/src/gui_qt/lib/namespace.py similarity index 97% rename from nmreval/gui_qt/lib/namespace.py rename to src/gui_qt/lib/namespace.py index 0083683..a5eb34f 100644 --- a/nmreval/gui_qt/lib/namespace.py +++ b/src/gui_qt/lib/namespace.py @@ -4,11 +4,12 @@ from collections import namedtuple import numpy as np -from ... import models -from ...configs import config_paths -from ...lib.importer import find_models, import_ -from ...utils import constants as constants -from ...utils.text import convert +from nmreval import models +from nmreval.configs import config_paths +from nmreval.lib.importer import find_models, import_ +from nmreval.utils import constants as constants +from nmreval.utils.text import convert + from ..Qt import QtWidgets, QtCore from .._py.namespace_widget import Ui_Form diff --git a/nmreval/gui_qt/lib/pg_objects.py b/src/gui_qt/lib/pg_objects.py similarity index 98% rename from nmreval/gui_qt/lib/pg_objects.py rename to src/gui_qt/lib/pg_objects.py index d412a06..3a287e6 100644 --- a/nmreval/gui_qt/lib/pg_objects.py +++ b/src/gui_qt/lib/pg_objects.py @@ -8,9 +8,9 @@ from pyqtgraph import ( LegendItem, ) -from ...lib.colors import BaseColor, Colors, TUColors -from ...lib.lines import LineStyle -from ...lib.symbols import SymbolStyle +from nmreval.lib.colors import BaseColor, Colors +from nmreval.lib.lines import LineStyle +from nmreval.lib.symbols import SymbolStyle from ..Qt import QtCore, QtGui @@ -274,6 +274,7 @@ class PlotItem(PlotDataItem): self.scatter.hide() def set_symbol(self, symbol=None, size=None, color=None): + print(symbol, type(symbol), isinstance(symbol, SymbolStyle)) if symbol is not None: if isinstance(symbol, int): self.setSymbol(SymbolStyle(symbol).to_str()) diff --git a/nmreval/gui_qt/lib/randpok.py b/src/gui_qt/lib/randpok.py similarity index 100% rename from nmreval/gui_qt/lib/randpok.py rename to src/gui_qt/lib/randpok.py diff --git a/nmreval/gui_qt/lib/spinboxes.py b/src/gui_qt/lib/spinboxes.py similarity index 100% rename from nmreval/gui_qt/lib/spinboxes.py rename to src/gui_qt/lib/spinboxes.py diff --git a/nmreval/gui_qt/lib/stuff.py b/src/gui_qt/lib/stuff.py similarity index 100% rename from nmreval/gui_qt/lib/stuff.py rename to src/gui_qt/lib/stuff.py diff --git a/nmreval/gui_qt/lib/styles.py b/src/gui_qt/lib/styles.py similarity index 100% rename from nmreval/gui_qt/lib/styles.py rename to src/gui_qt/lib/styles.py diff --git a/nmreval/gui_qt/lib/tables.py b/src/gui_qt/lib/tables.py similarity index 100% rename from nmreval/gui_qt/lib/tables.py rename to src/gui_qt/lib/tables.py diff --git a/nmreval/gui_qt/lib/undos.py b/src/gui_qt/lib/undos.py similarity index 100% rename from nmreval/gui_qt/lib/undos.py rename to src/gui_qt/lib/undos.py diff --git a/nmreval/gui_qt/lib/usermodeleditor.py b/src/gui_qt/lib/usermodeleditor.py similarity index 100% rename from nmreval/gui_qt/lib/usermodeleditor.py rename to src/gui_qt/lib/usermodeleditor.py diff --git a/nmreval/gui_qt/lib/utils.py b/src/gui_qt/lib/utils.py similarity index 100% rename from nmreval/gui_qt/lib/utils.py rename to src/gui_qt/lib/utils.py diff --git a/nmreval/gui_qt/main/__init__.py b/src/gui_qt/main/__init__.py similarity index 100% rename from nmreval/gui_qt/main/__init__.py rename to src/gui_qt/main/__init__.py diff --git a/nmreval/gui_qt/main/mainwindow.py b/src/gui_qt/main/mainwindow.py similarity index 99% rename from nmreval/gui_qt/main/mainwindow.py rename to src/gui_qt/main/mainwindow.py index c0090b3..5dd24f6 100644 --- a/nmreval/gui_qt/main/mainwindow.py +++ b/src/gui_qt/main/mainwindow.py @@ -1,11 +1,14 @@ +from __future__ import annotations + import pathlib import re from pathlib import Path -from typing import List, Tuple from numpy import geomspace, linspace from pyqtgraph import ViewBox, PlotDataItem +from nmreval.configs import * + from .management import UpperManagement from ..Qt import QtCore, QtGui, QtPrintSupport, QtWidgets from ..data.shift_graphs import QShift @@ -24,7 +27,6 @@ from ..math.smooth import QSmooth from ..nmr.coupling_calc import QCoupCalcDialog from ..nmr.t1_from_tau import QRelaxCalc from .._py.basewindow import Ui_BaseWindow -from ...configs import * class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow): @@ -268,7 +270,7 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow): @QtCore.pyqtSlot() @QtCore.pyqtSlot(list) - def save_fit_parameter(self, fit_sets: List[str] = None): + def save_fit_parameter(self, fit_sets: list[str] = None): fname, _ = QtWidgets.QFileDialog.getSaveFileName(self, 'Save fit parameter', directory=str(self.path), filter='All files(*, *);;Text files(*.dat *.txt)') @@ -472,7 +474,7 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow): self._set_pick_block(pick_required, block_window) - def _select_ptswidget(self, onoff: bool, pick_required: bool, block_window: bool) -> Tuple[bool, bool]: + def _select_ptswidget(self, onoff: bool, pick_required: bool, block_window: bool) -> tuple[bool, bool]: if self.current_graph_widget is None: return pick_required, block_window diff --git a/nmreval/gui_qt/main/management.py b/src/gui_qt/main/management.py similarity index 98% rename from nmreval/gui_qt/main/management.py rename to src/gui_qt/main/management.py index fc0f9a5..bfbde4d 100644 --- a/nmreval/gui_qt/main/management.py +++ b/src/gui_qt/main/management.py @@ -5,15 +5,15 @@ import re import uuid from typing import List -from ...fit import data as fit_d -from ...fit.model import Model -from ...fit.result import FitResult -from ...fit.minimizer import FitRoutine -from ...lib.colors import TUColorsC, available_cycles -from ...math.interpol import interpolate -from ...math.logfourier import logft -from ...math.smooth import smooth -from ...nmr.relaxation import Relaxation +from nmreval.fit import data as fit_d +from nmreval.fit.model import Model +from nmreval.fit.result import FitResult +from nmreval.fit.minimizer import FitRoutine +from nmreval.lib.colors import TUColorsC, available_cycles +from nmreval.math.interpol import interpolate +from nmreval.math.logfourier import logft +from nmreval.math.smooth import smooth +from nmreval.nmr.relaxation import Relaxation from ..lib.undos import * from ..data.container import * diff --git a/nmreval/io/__init__.py b/src/gui_qt/math/__init__.py similarity index 100% rename from nmreval/io/__init__.py rename to src/gui_qt/math/__init__.py diff --git a/nmreval/gui_qt/math/bootstrap.py b/src/gui_qt/math/bootstrap.py similarity index 100% rename from nmreval/gui_qt/math/bootstrap.py rename to src/gui_qt/math/bootstrap.py diff --git a/nmreval/gui_qt/math/evaluation.py b/src/gui_qt/math/evaluation.py similarity index 98% rename from nmreval/gui_qt/math/evaluation.py rename to src/gui_qt/math/evaluation.py index 112b5fb..617e5f9 100644 --- a/nmreval/gui_qt/math/evaluation.py +++ b/src/gui_qt/math/evaluation.py @@ -1,6 +1,5 @@ from ..Qt import QtCore, QtWidgets, QtGui from .._py.eval_expr_dialog import Ui_CalcDialog -from ..lib.namespace import Namespace class QEvalDialog(QtWidgets.QDialog, Ui_CalcDialog): diff --git a/nmreval/gui_qt/math/integrate_derive.py b/src/gui_qt/math/integrate_derive.py similarity index 100% rename from nmreval/gui_qt/math/integrate_derive.py rename to src/gui_qt/math/integrate_derive.py diff --git a/nmreval/gui_qt/math/interpol.py b/src/gui_qt/math/interpol.py similarity index 100% rename from nmreval/gui_qt/math/interpol.py rename to src/gui_qt/math/interpol.py diff --git a/nmreval/gui_qt/math/mean_dialog.py b/src/gui_qt/math/mean_dialog.py similarity index 97% rename from nmreval/gui_qt/math/mean_dialog.py rename to src/gui_qt/math/mean_dialog.py index 18b60fd..4fd0d87 100644 --- a/nmreval/gui_qt/math/mean_dialog.py +++ b/src/gui_qt/math/mean_dialog.py @@ -1,4 +1,5 @@ -from ...distributions import ColeDavidson, HavriliakNegami, KWW, LogGaussian +from nmreval.distributions import ColeDavidson, HavriliakNegami, KWW, LogGaussian + from ..Qt import QtWidgets, QtCore from .._py.meandialog import Ui_calc_means_dialog from ..lib.forms import Widget diff --git a/nmreval/gui_qt/math/skipping.py b/src/gui_qt/math/skipping.py similarity index 100% rename from nmreval/gui_qt/math/skipping.py rename to src/gui_qt/math/skipping.py diff --git a/nmreval/gui_qt/math/smooth.py b/src/gui_qt/math/smooth.py similarity index 100% rename from nmreval/gui_qt/math/smooth.py rename to src/gui_qt/math/smooth.py diff --git a/nmreval/lib/__init__.py b/src/gui_qt/nmr/__init__.py similarity index 100% rename from nmreval/lib/__init__.py rename to src/gui_qt/nmr/__init__.py diff --git a/nmreval/gui_qt/nmr/coupling_calc.py b/src/gui_qt/nmr/coupling_calc.py similarity index 96% rename from nmreval/gui_qt/nmr/coupling_calc.py rename to src/gui_qt/nmr/coupling_calc.py index ecd0632..30f146a 100644 --- a/nmreval/gui_qt/nmr/coupling_calc.py +++ b/src/gui_qt/nmr/coupling_calc.py @@ -1,5 +1,5 @@ -from ...nmr.coupling import * -from ...utils.text import convert +from nmreval.nmr.coupling import * +from nmreval.utils.text import convert from ..Qt import QtWidgets, QtCore from .._py.coupling_calculator import Ui_coupling_calc_dialog diff --git a/nmreval/gui_qt/nmr/t1_from_tau.py b/src/gui_qt/nmr/t1_from_tau.py similarity index 96% rename from nmreval/gui_qt/nmr/t1_from_tau.py rename to src/gui_qt/nmr/t1_from_tau.py index f7f3557..5e16eba 100644 --- a/nmreval/gui_qt/nmr/t1_from_tau.py +++ b/src/gui_qt/nmr/t1_from_tau.py @@ -1,9 +1,9 @@ -from typing import List, Tuple +from __future__ import annotations -from ...nmr.coupling import * -from ...distributions import ColeCole, ColeDavidson, HavriliakNegami, KWW, LogGaussian -from ...utils import pi -from ...utils.text import convert +from nmreval.nmr.coupling import * +from nmreval.distributions import ColeCole, ColeDavidson, HavriliakNegami, KWW, LogGaussian +from nmreval.utils import pi +from nmreval.utils.text import convert from ..Qt import QtGui, QtCore, QtWidgets from ..lib.forms import SelectionWidget, Widget @@ -59,7 +59,7 @@ class QRelaxCalc(QtWidgets.QDialog, Ui_Dialog): self.update_coupling_model(self.coupling_combobox.currentIndex()) self.tau_graph_changed(self.tau_graph_combobox.currentIndex()) - def update_graphs(self, graphs: List[Tuple[str, str]]): + def update_graphs(self, graphs: list[tuple[str, str]]): current_id = self.graph_combobox.currentData() self.graph_combobox.clear() for (gid, name) in graphs: diff --git a/nmreval/gui_qt/nmr/t1widget.py b/src/gui_qt/nmr/t1widget.py similarity index 98% rename from nmreval/gui_qt/nmr/t1widget.py rename to src/gui_qt/nmr/t1widget.py index f615080..2521224 100644 --- a/nmreval/gui_qt/nmr/t1widget.py +++ b/src/gui_qt/nmr/t1widget.py @@ -1,12 +1,12 @@ import numpy as np from pyqtgraph import mkBrush, mkPen -from ..lib.pg_objects import PlotItem -from ...data.points import Points -from ...nmr.relaxation import RelaxationEvaluation -from ...nmr.coupling import * -from ...distributions import * +from nmreval.data.points import Points +from nmreval.nmr.relaxation import RelaxationEvaluation +from nmreval.nmr.coupling import * +from nmreval.distributions import * +from ..lib.pg_objects import PlotItem from ..Qt import QtCore, QtWidgets, QtGui from .._py.t1dialog import Ui_t1dialog from ..lib.forms import FormWidget, SelectionWidget diff --git a/nmreval/__init__.py b/src/nmreval/__init__.py similarity index 100% rename from nmreval/__init__.py rename to src/nmreval/__init__.py diff --git a/nmreval/bds/__init__.py b/src/nmreval/bds/__init__.py similarity index 100% rename from nmreval/bds/__init__.py rename to src/nmreval/bds/__init__.py diff --git a/nmreval/configs.py b/src/nmreval/configs.py similarity index 100% rename from nmreval/configs.py rename to src/nmreval/configs.py diff --git a/nmreval/data/__init__.py b/src/nmreval/data/__init__.py similarity index 100% rename from nmreval/data/__init__.py rename to src/nmreval/data/__init__.py diff --git a/nmreval/data/bds.py b/src/nmreval/data/bds.py similarity index 100% rename from nmreval/data/bds.py rename to src/nmreval/data/bds.py diff --git a/nmreval/data/dsc.py b/src/nmreval/data/dsc.py similarity index 100% rename from nmreval/data/dsc.py rename to src/nmreval/data/dsc.py diff --git a/nmreval/data/nmr.py b/src/nmreval/data/nmr.py similarity index 99% rename from nmreval/data/nmr.py rename to src/nmreval/data/nmr.py index 23d501a..8f5229a 100644 --- a/nmreval/data/nmr.py +++ b/src/nmreval/data/nmr.py @@ -1,5 +1,4 @@ import warnings -from typing import Union import numpy as np diff --git a/nmreval/data/points.py b/src/nmreval/data/points.py similarity index 94% rename from nmreval/data/points.py rename to src/nmreval/data/points.py index a9c4fc3..926b9c4 100644 --- a/nmreval/data/points.py +++ b/src/nmreval/data/points.py @@ -1,7 +1,9 @@ +from __future__ import annotations + import copy from numbers import Number, Real from pathlib import Path -from typing import Any, List, Optional, Tuple, TypeVar, Union +from typing import Any, TypeVar import numpy as np try: @@ -25,7 +27,7 @@ class Points: y_err (array_like, optional): errors """ - def __init__(self, x: ArrayLike, y: ArrayLike, y_err: Optional[ArrayLike] = None, **kwargs: Any): + def __init__(self, x: ArrayLike, y: ArrayLike, y_err: ArrayLike = None, **kwargs: Any): self._x, self._y, self._y_err, self.mask = self._prepare_xy(x, y, y_err=y_err) @@ -57,7 +59,7 @@ class Points: self.name = str(value) @staticmethod - def _prepare_xy(x: ArrayLike, y: ArrayLike, y_err: Optional[ArrayLike] = None): + def _prepare_xy(x: ArrayLike, y: ArrayLike, y_err: ArrayLike = None): x = np.atleast_1d(x).astype(float) if x.ndim > 1: raise TypeError('x axis cannot be multidimensional') @@ -270,9 +272,9 @@ class Points: def length(self): return len(self._x) - def points(self, idx: Optional[list] = None, special: Optional[str] = None, - avg_range: Tuple[int, int] = (0, 0), avg_mode: str = 'mean', - pts: Optional[list] = None) -> List[tuple]: + def points(self, idx: list = None, special: str = None, + avg_range: tuple[int, int] = (0, 0), avg_mode: str = 'mean', + pts: list = None) -> list[tuple]: """ Return (x, y) values at specified positions. @@ -351,7 +353,7 @@ class Points: return pts - def _average(self, mode: str, idx, left: int, right: int) -> Tuple[float, float]: + def _average(self, mode: str, idx, left: int, right: int) -> tuple[float, float]: if mode == 'mean': y_mean = np.mean(self._y[self.mask][left:right].real) y_err = np.linalg.norm(self._y_err[self.mask][left:right]) / (right - left) @@ -388,7 +390,7 @@ class Points: return self - def integrate(self, log: bool = False, limits: Tuple[float, float] = None) -> PointLike: + def integrate(self, log: bool = False, limits: tuple[float, float] = None) -> PointLike: new_data = self.copy() if limits is not None: @@ -401,7 +403,7 @@ class Points: return new_data - def diff(self, log: bool = False, limits: Optional[Tuple[float, float]] = None) -> PointLike: + def diff(self, log: bool = False, limits: tuple[float, float] = None) -> PointLike: """ Calculate first derivate :math:`dy/dx` or :math:`dy/d(\ln x)`. @@ -447,7 +449,7 @@ class Points: """ return copy.deepcopy(self) - def get_values(self, idx: int) -> Tuple[np.ndarray, np.ndarray, np.ndarray]: + def get_values(self, idx: int) -> tuple[np.ndarray, np.ndarray, np.ndarray]: """ Return values at a given index @@ -459,7 +461,7 @@ class Points: """ return self._x[idx], self._y[idx], self._y_err[idx] - def set_values(self, idx: int, value: Union[list, tuple, np.ndarray]) -> PointLike: + def set_values(self, idx: int, value: list | tuple | np.ndarray) -> PointLike: if not (isinstance(value, (list, tuple, np.ndarray)) and (len(value) in [2, 3])): raise TypeError('Values should be list type of length 2 or 3') @@ -473,10 +475,7 @@ class Points: return self - def set_data(self, - x: Optional[np.ndarray] = None, - y: Optional[np.ndarray] = None, - y_err: Optional[np.ndarray] = None) -> PointLike: + def set_data(self, x: np.ndarray = None, y: np.ndarray = None, y_err: np.ndarray = None) -> PointLike: if x is None: x = self._x if y is None: @@ -488,7 +487,7 @@ class Points: return self - def append(self, x: ArrayLike, y: ArrayLike, y_err: Optional[ArrayLike] = None): + def append(self, x: ArrayLike, y: ArrayLike, y_err: ArrayLike = None): x, y, y_err, mask = self._prepare_xy(x, y, y_err) self._x = np.r_[self._x, x] diff --git a/nmreval/data/signals.py b/src/nmreval/data/signals.py similarity index 96% rename from nmreval/data/signals.py rename to src/nmreval/data/signals.py index c4cf9b1..5a408cb 100644 --- a/nmreval/data/signals.py +++ b/src/nmreval/data/signals.py @@ -1,6 +1,5 @@ import numpy as np - from .points import Points @@ -48,10 +47,10 @@ class Signal(Points): return self def manual_phase(self, ph0: float = 0., ph1: float = 0., pvt: float = 0): - self._y *= np.exp(1j * ph0 * np.pi / 180.) + self._y *= np.exp(-1j * ph0 * np.pi / 180.) if ph1 != 0: x = (self._x - pvt) / max(self._x) - self._y *= np.exp(1j * x * ph1 * np.pi / 180.) + self._y *= np.exp(-1j * x * ph1 * np.pi / 180.) self.meta['phase'].append((ph0, ph1, pvt)) return self diff --git a/nmreval/distributions/__init__.py b/src/nmreval/distributions/__init__.py similarity index 93% rename from nmreval/distributions/__init__.py rename to src/nmreval/distributions/__init__.py index 741b106..3489da6 100644 --- a/nmreval/distributions/__init__.py +++ b/src/nmreval/distributions/__init__.py @@ -9,7 +9,6 @@ types of correlation times. .. autosummary:: :toctree: generated/ - :template: autosummary/class_with_attributes.rst :nosignatures: Debye diff --git a/nmreval/distributions/base.py b/src/nmreval/distributions/base.py similarity index 95% rename from nmreval/distributions/base.py rename to src/nmreval/distributions/base.py index fb6eda8..ae9b72e 100644 --- a/nmreval/distributions/base.py +++ b/src/nmreval/distributions/base.py @@ -1,5 +1,7 @@ +from __future__ import annotations + import abc -from typing import Any, Union +from typing import Any import numpy as np @@ -31,7 +33,7 @@ class Distribution(abc.ABC): pass @classmethod - def specdens(cls, omega: ArrayLike, tau: ArrayLike, *args: Any) -> Union[np.ndarray, float]: + def specdens(cls, omega: ArrayLike, tau: ArrayLike, *args: Any) -> np.ndarray | float: return cls.susceptibility(omega, tau, *args).imag / omega @classmethod diff --git a/nmreval/distributions/colecole.py b/src/nmreval/distributions/colecole.py similarity index 59% rename from nmreval/distributions/colecole.py rename to src/nmreval/distributions/colecole.py index cc10f8d..b8551a8 100644 --- a/nmreval/distributions/colecole.py +++ b/src/nmreval/distributions/colecole.py @@ -1,7 +1,8 @@ +from __future__ import annotations + import numpy as np from .base import Distribution -from ..lib.utils import ArrayLike from ..lib.decorator import adjust_dims from ..math.mittagleffler import mlf @@ -19,29 +20,23 @@ class ColeCole(Distribution): """ Distribution of correlation times - .. math:: - G(\ln\\tau) = \\frac{1}{2\pi} \\frac{\\sin(\\pi\\alpha)}{\cosh[\\alpha\ln(\\tau/\\tau_0)] + \cos(\\alpha \pi))} - Args: - tau: - tau0: - alpha: + tau (array_like): + tau0 (array_like): + alpha (float): """ z = np.log(tau/tau0) return np.sin(np.pi*alpha)/(np.cosh(z*alpha) + np.cos(alpha*np.pi))/(2*np.pi) @staticmethod @adjust_dims - def susceptibility(omega: ArrayLike, tau: ArrayLike, alpha: float) -> ArrayLike: + def susceptibility(omega, tau, alpha: float): r""" Complex susceptibility - .. math:: - \chi(\omega, \tau, \alpha) = \frac{1}{[1-(i\omega\tau)^\alpha]} - Args: - omega (array-like): Frequency axis in 1/s (not Hz). - tau (array-like): Correlation times :math:`\tau_\text{CC}` in s. + omega (array_like): Frequency axis in 1/s (not Hz). + tau (array_like): Correlation times :math:`\tau_\text{CC}` in s. alpha (float): Shape parameter. """ @@ -54,13 +49,10 @@ class ColeCole(Distribution): """ Spectral density - .. math:: - J(\omega, \\tau, \\alpha) = \\frac{\sin(\\alpha\pi/2)(\omega\\tau)^\\alpha}{\omega[1+(\omega\\tau)^{2\\alpha} + 2\\pi\cos(\\alpha\pi/2)(\omega\\tau)^\\alpha]} - Args: - omega: - tau: - alpha: + omega (array_like): + tau (array_like): + alpha (float): """ omtau = (omega*tau)**alpha return np.sin(alpha*np.pi/2) * omtau / (1 + omtau**2 + 2*np.cos(alpha*np.pi/2)*omtau) / omega @@ -71,14 +63,11 @@ class ColeCole(Distribution): """ Correlation function :math:`C(t)` - .. math:: - C(t) = E_\\alpha[-(t/\\tau_0)^\\alpha] - with Mittag-Leffler function :math:`E_a(x)` Args: - t: - tau0: - alpha: + t (array_like): + tau0 (array_like): + alpha (float): """ return mlf(-(t/tau0)**alpha, alpha) diff --git a/nmreval/distributions/coledavidson.py b/src/nmreval/distributions/coledavidson.py similarity index 93% rename from nmreval/distributions/coledavidson.py rename to src/nmreval/distributions/coledavidson.py index f19bf57..576bca5 100644 --- a/nmreval/distributions/coledavidson.py +++ b/src/nmreval/distributions/coledavidson.py @@ -1,11 +1,10 @@ -import numbers +from __future__ import annotations import numpy as np from scipy.special import psi, gammaincc from .base import Distribution from ..lib.decorator import adjust_dims -from ..lib.utils import ArrayLike from ..utils.constants import Eu @@ -44,7 +43,7 @@ class ColeDavidson(Distribution): @staticmethod @adjust_dims - def susceptibility(omega: ArrayLike, tau: ArrayLike, gamma: float) -> ArrayLike: + def susceptibility(omega: float | np.ndarray, tau: float | np.ndarray, gamma: float) -> float | np.ndarray: r""" Complex susceptibility @@ -52,8 +51,8 @@ class ColeDavidson(Distribution): \chi(\omega, \tau, \alpha, \gamma) = \frac{1}{[1-i\omega\tau]^\gamma} Args: - omega (array-like): Frequency axis in 1/s (not Hz). - tau (array-like): Correlation times in s. + omega (array_like): Frequency axis in 1/s (not Hz). + tau (array_like): Correlation times in s. gamma (float): Shape parameter. """ diff --git a/nmreval/distributions/debye.py b/src/nmreval/distributions/debye.py similarity index 89% rename from nmreval/distributions/debye.py rename to src/nmreval/distributions/debye.py index d342648..2fae2de 100644 --- a/nmreval/distributions/debye.py +++ b/src/nmreval/distributions/debye.py @@ -34,8 +34,8 @@ class Debye(Distribution): \chi(\omega, \tau) = \frac{1}{1-i\omega\tau} Args: - omega (array-like): Frequency axis in 1/s (not Hz). - tau (array-like): Correlation times in s. + omega (array_like): Frequency axis in 1/s (not Hz). + tau (array_like): Correlation times in s. """ return 1/(1 - 1j*omega*tau) diff --git a/nmreval/distributions/energy.py b/src/nmreval/distributions/energy.py similarity index 66% rename from nmreval/distributions/energy.py rename to src/nmreval/distributions/energy.py index 33653cc..a97a462 100644 --- a/nmreval/distributions/energy.py +++ b/src/nmreval/distributions/energy.py @@ -1,9 +1,10 @@ from itertools import product import numpy as np -from scipy.integrate import simps as simpson +from scipy.integrate import quad, simps as simpson from .base import Distribution +from ..lib.utils import ArrayLike from ..utils.constants import kB @@ -44,17 +45,8 @@ class EnergyBarriers(Distribution): return ret_val @staticmethod - def susceptibility(omega, temperature, *args): + def susceptibility(omega: ArrayLike, temperature: ArrayLike, tau0: float, e_m: float, e_b: float) -> ArrayLike: # in contrast to other spectral densities, it's omega and temperature - tau0, e_m, e_b = args - - def integrand_real(e_a, w, t0, mu, sigma, t): - r = EnergyBarriers.rate(t0, e_a, t) - return 1/(r**2 + w**2) * EnergyBarriers.energydistribution(e_a, mu, sigma) - - def integrand_imag(e_a, w, t0, mu, sigma, t): - r = EnergyBarriers.rate(t0, e_a, t) - return w*r/(r**2 + w**2) * EnergyBarriers.energydistribution(e_a, mu, sigma) omega = np.atleast_1d(omega) temperature = np.atleast_1d(temperature) @@ -62,8 +54,8 @@ class EnergyBarriers(Distribution): e_axis = np.linspace(max(0, e_m-50*e_b), e_m+50*e_b, num=5001) ret_val = [] for o, tt in product(omega, temperature): - ret_val.append(simpson(integrand_real(e_axis, o, tau0, e_m, e_b, tt), e_axis) - - 1j * simpson(integrand_imag(e_axis, o, tau0, e_m, e_b, tt), e_axis)) + ret_val.append(simpson(_integrand_freq_real(e_axis, o, tau0, e_m, e_b, tt), e_axis) - + 1j * simpson(_integrand_freq_imag(e_axis, o, tau0, e_m, e_b, tt), e_axis)) return np.array(ret_val) @@ -97,3 +89,32 @@ class EnergyBarriers(Distribution): @staticmethod def max(*args): return args[1] * np.exp(args[2] / (kB * args[0])) + + +def _integrate_process_imag(args): + pass + + +def _integrate_process_real(args): + omega_i, t, tau0, mu, sigma, temp_j = args + return quad(_integrand_freq_real(), 0, 10, args=(omega_i, t, tau0, mu, sigma, temp_j))[0] + + +def _integrate_process_time(args): + omega_i, t, tau0, mu, sigma, temp_j = args + return quad(_integrand_time, 0, 10, args=(omega_i, t, tau0, mu, sigma, temp_j))[0] + + +def _integrand_freq_real(u, omega, tau0, mu, sigma, temp): + r = EnergyBarriers.rate(tau0, u, temp) + return 1 / (r**2 + omega**2) * EnergyBarriers.energydistribution(u, mu, sigma) + + +def _integrand_freq_imag(u, omega, tau0, mu, sigma, temp): + rate = EnergyBarriers.rate(tau0, u, temp) + return omega * rate / (rate**2 + omega**2) * EnergyBarriers.energydistribution(u, mu, sigma) + + +def _integrand_time(u, t, tau0, mu, sigma, temp): + rate = EnergyBarriers.rate(tau0, u, temp) + return EnergyBarriers.energydistribution(u, mu, sigma) * np.exp(-t*rate) diff --git a/src/nmreval/distributions/gengamma.py b/src/nmreval/distributions/gengamma.py new file mode 100644 index 0000000..47b0479 --- /dev/null +++ b/src/nmreval/distributions/gengamma.py @@ -0,0 +1,178 @@ +from __future__ import annotations + +from abc import ABC + +import numpy as np +try: + from scipy.integrate import simpson +except ImportError: + from scipy.integrate import simps as simpson +from scipy.special import gammaln + +from nmreval.distributions.base import Distribution +from nmreval.math.logfourier import logft + + +class AbstractGG(Distribution, ABC): + """ + Base class for general gamma functions + """ + + @classmethod + def correlation(cls, t, tau0, *args): + tt = np.asanyarray(t) + taus, ln_tau = AbstractGG._prepare_integration(tau0) + g_tau = cls.distribution(taus, tau0, *args) + ret_val = np.array([simpson(np.exp(-t_i/taus) * g_tau, ln_tau) for t_i in tt]) + + return ret_val + + @classmethod + def susceptibility(cls, omega, tau0, *args): + r""" + Calculate spectral density \int G(ln(tau) tau/(1+(w*tau)^2) dln(tau) + """ + w = np.asanyarray(omega) + taus, ln_tau = AbstractGG._prepare_integration(tau0) + g_tau = cls.distribution(taus, tau0, *args) + + ret_val = np.array([simpson(g_tau / (1 - 1j*w_i*taus), ln_tau) for w_i in w]) + + return ret_val + + @classmethod + def specdens(cls, omega, tau0, *args): + r""" + Calculate spectral density \int G(ln(tau) tau/(1+(w*tau)^2) dln(tau) + """ + w = np.asanyarray(omega) + taus, ln_tau = AbstractGG._prepare_integration(tau0) + g_tau = cls.distribution(taus, tau0, *args) + + ret_val = np.array([simpson(g_tau * taus / (1 + (w_i*taus)**2), ln_tau) for w_i in w]) + + return ret_val + + @staticmethod + def _prepare_integration( + tau0: float, limits: tuple[int, int] = (20, 20), num_steps: int = 4001 + ) -> tuple[np.ndarray, np.ndarray]: + """ + Create array of correlation times for integration over ln(tau) + Args: + tau0 (float): center of correlation times + limits (tuple of int): Define limits ln(tau0)-limits[0] and ln(tau0)+limits[1] of array. Default is (20, 20) + num_steps (int): length of array. Default is 4001 + + Returns: + array of taus and array of ln(tau) + + """ + + ln_tau0 = np.log(tau0) + ln_tau = np.linspace(ln_tau0-limits[0], ln_tau0+limits[1], num=num_steps) + + return np.exp(ln_tau), ln_tau + + +# noinspection PyMethodOverriding +class GGAlpha(AbstractGG): + name = r'General \Gamma (\alpha)' + parameter = [r'\tau', r'\alpha', r'\beta'] + + @staticmethod + def distribution(taus: float | np.ndarray, tau: float, alpha: float, beta: float) -> float | np.ndarray: + b_to_a = beta / alpha + norm = np.exp(gammaln(b_to_a) - b_to_a * np.log(b_to_a)) / alpha + t_to_t0 = taus / tau + ret_val = np.exp(-b_to_a * t_to_t0**alpha) * t_to_t0**beta + + return ret_val / norm + + +# noinspection PyMethodOverriding +class GGAlphaEW(AbstractGG): + name = r'General \Gamma (\alpha + EW)' + parameter = [r'\tau', r'\alpha', r'\beta', r'\sigma', r'\gamma'] + + @staticmethod + def distribution(tau: float | np.ndarray, tau0: float, + alpha: float, beta: float, sigma: float, gamma: float) -> float | np.ndarray: + + if gamma == beta or sigma == 0: + return GGAlpha.distribution(tau, tau0, alpha, beta) + + b_to_a = beta / alpha + ln_b_to_a = np.log(b_to_a) + g_to_a = gamma / alpha + t_to_t0 = tau / tau0 + + norm = (np.exp(gammaln(b_to_a)) + sigma**(gamma-beta) * np.exp(gammaln(g_to_a) + (b_to_a-g_to_a)*ln_b_to_a)) / \ + np.exp(b_to_a*ln_b_to_a) / alpha + + ret_val = np.exp(-b_to_a * t_to_t0**alpha) * t_to_t0**beta * (1 + (t_to_t0*sigma)**(gamma-beta)) + + return ret_val / norm + + +# noinspection PyMethodOverriding +class GGBeta(AbstractGG): + name = r'General \Gamma (\beta)' + parameter = [r'\tau', 'a', 'b'] + + @staticmethod + def distribution(tau: float | np.ndarray, tau0: float, a: float, b: float) -> float | np.ndarray: + norm = a * (1+b) * np.sin(np.pi*b/(1+b)) * b**(b/(1+b)) / np.pi + ret_val = b * (tau/tau0)**a + (tau/tau0)**(-a*b) + + return norm / ret_val + + +class GGAlphaEWBeta(Distribution): + name = r'General Gamma (WW (\alpha + EW), \beta)' + parameter = [ + r'\tau_{\alpha}', r'\alpha', r'\beta', r'\sigma', r'\gamma', + r'\tau_{\beta}', 'a', 'b', 'R' + ] + + @staticmethod + def distribution(tau, tau0, *args): + pass + + @staticmethod + def correlation(t, *args): + tau_alpha, alpha, beta, sigma, gamma, tau_beta, a, b, r = args + if r == 0: + return GGAlphaEW.correlation(t, tau_alpha, alpha, beta, sigma, gamma) + elif r == 1: + return GGBeta.correlation(t, tau_beta, a, b) + + gg_alpha = GGAlphaEW.correlation(t, tau_alpha, alpha, beta, sigma, gamma) + gg_beta = GGBeta.correlation(t, tau_beta, a, b) + + return ((1-r)*gg_beta + r) * gg_alpha + + @staticmethod + def susceptibility(omega, *args): + t_axis, corr = GGAlphaEWBeta._correlation_for_ft(omega, *args) + + ft = logft(t_axis, corr, new_x=omega, mode='complex')[1] + + return 1 + omega * ft.imag + 1j * omega * ft.real + + @staticmethod + def specdens(omega, *args): + t_axis, corr = GGAlphaEWBeta._correlation_for_ft(omega, *args) + + return logft(t_axis, corr, new_x=omega, mode='real')[1] + + @staticmethod + def _correlation_for_ft(omega, *args): + # time axis for correlation function + additional_decades = 5 + lower_limit = np.log10(1 / np.max(omega)) - additional_decades + upper_limit = np.log10(1 / np.min(omega)) + additional_decades + num_steps = int(len(omega) * additional_decades) + t_axis = np.logspace(lower_limit, upper_limit, num=num_steps) + + return t_axis, GGAlphaEWBeta.correlation(t_axis, *args) diff --git a/nmreval/distributions/havriliaknegami.py b/src/nmreval/distributions/havriliaknegami.py similarity index 88% rename from nmreval/distributions/havriliaknegami.py rename to src/nmreval/distributions/havriliaknegami.py index e5d5986..9c12960 100644 --- a/nmreval/distributions/havriliaknegami.py +++ b/src/nmreval/distributions/havriliaknegami.py @@ -1,5 +1,3 @@ -from typing import Union - import numpy as np from scipy.special import psi @@ -30,7 +28,7 @@ class HavriliakNegami(Distribution): Args: tau (array_like) : - tau0 (array-like) : + tau0 (array_like) : alpha: gamma: @@ -68,8 +66,8 @@ class HavriliakNegami(Distribution): \text{E}_{a,b}^g (z) = \frac{1}{\Gamma(g)} \sum_{k=0}^\infty \frac{\Gamma(g+k) z^k}{k!\Gamma(ak+b)} Args: - t (array-like): Time axis in s. - tau (array-like): Correlation times :math:`\tau_\text{HN}` in s. + t (array_like): Time axis in s. + tau (array_like): Correlation times :math:`\tau_\text{HN}` in s. alpha (float): Cole-Cole shape parameter. gamma (float): Cole-Davidson shape parameter. @@ -82,7 +80,7 @@ class HavriliakNegami(Distribution): @staticmethod @adjust_dims - def susceptibility(omega: ArrayLike, tau: ArrayLike, alpha: float, gamma: float) -> Union[np.ndarray, complex]: + def susceptibility(omega: ArrayLike, tau: ArrayLike, alpha: float, gamma: float) -> ArrayLike: r""" Complex susceptibility @@ -90,8 +88,8 @@ class HavriliakNegami(Distribution): \chi(\omega, \tau, \alpha, \gamma) = \frac{1}{[1-(i\omega\tau)^\alpha]^\gamma} Args: - omega (array-like): Frequency axis in 1/s (not Hz). - tau (array-like): Correlation times in s. + omega (array_like): Frequency axis in 1/s (not Hz). + tau (array_like): Correlation times in s. alpha (float): Shape parameter. gamma (float): Even more shape parameter. @@ -100,7 +98,7 @@ class HavriliakNegami(Distribution): @staticmethod @adjust_dims - def specdens(omega: ArrayLike, tau: ArrayLike, alpha: float, gamma: float) -> Union[np.ndarray, float]: + def specdens(omega: ArrayLike, tau: ArrayLike, alpha: float, gamma: float) -> ArrayLike: r""" Spectral density :math:`J(\omega)` @@ -109,8 +107,8 @@ class HavriliakNegami(Distribution): {\omega \left[ 1+(\omega\tau)^\alpha \cos(\alpha\pi/2) + (\omega\tau)^{2\alpha} \right]^{\gamma/2}} Args: - omega (array-like): Frequency axis in 1/s (not Hz). - tau (array-like): Correlation times in s. + omega (array_like): Frequency axis in 1/s (not Hz). + tau (array_like): Correlation times in s. alpha (float): Cole-Cole shape parameter. gamma (float): Cole-Davidson shape parameter. @@ -127,7 +125,7 @@ class HavriliakNegami(Distribution): return result @staticmethod - def mean(tau: ArrayLike, alpha: float, gamma: float) -> Union[np.ndarray, float]: + def mean(tau: ArrayLike, alpha: float, gamma: float) -> ArrayLike: r""" .. math:: @@ -136,7 +134,7 @@ class HavriliakNegami(Distribution): This is an approximation given in `[1]`_ Args: - tau (array-like): Function parameter in s. + tau (array_like): Function parameter in s. alpha (float): Shape parameter. gamma (float): Even more shape parameter. diff --git a/nmreval/distributions/intermolecular.py b/src/nmreval/distributions/intermolecular.py similarity index 100% rename from nmreval/distributions/intermolecular.py rename to src/nmreval/distributions/intermolecular.py diff --git a/nmreval/distributions/kww.py b/src/nmreval/distributions/kww.py similarity index 100% rename from nmreval/distributions/kww.py rename to src/nmreval/distributions/kww.py diff --git a/nmreval/distributions/loggaussian.py b/src/nmreval/distributions/loggaussian.py similarity index 98% rename from nmreval/distributions/loggaussian.py rename to src/nmreval/distributions/loggaussian.py index 62cf0b3..e1736c8 100644 --- a/nmreval/distributions/loggaussian.py +++ b/src/nmreval/distributions/loggaussian.py @@ -3,8 +3,6 @@ from itertools import product import numpy as np -from ..lib.decorator import adjust_dims - try: from scipy.integrate import simpson except ImportError: diff --git a/nmreval/math/__init__.py b/src/nmreval/dsc/__init__.py similarity index 100% rename from nmreval/math/__init__.py rename to src/nmreval/dsc/__init__.py diff --git a/nmreval/dsc/calibration.py b/src/nmreval/dsc/calibration.py similarity index 99% rename from nmreval/dsc/calibration.py rename to src/nmreval/dsc/calibration.py index 1b293f7..bfae765 100644 --- a/nmreval/dsc/calibration.py +++ b/src/nmreval/dsc/calibration.py @@ -1,5 +1,3 @@ -__version__ = '0.1.3' - import os import argparse import sys @@ -9,7 +7,8 @@ import matplotlib.pyplot as plt import scipy.interpolate from scipy.integrate import simps -from nmreval.io.dsc import DSCSample, Cyclohexane +from ..io.dsc import DSCSample, Cyclohexane + parser = argparse.ArgumentParser(description='Calibrate DSC data') parser.add_argument('sample', type=str, help='filename of DSC sample') diff --git a/nmreval/dsc/dsc_calibration_fast_neu.py b/src/nmreval/dsc/dsc_calibration_fast_neu.py similarity index 100% rename from nmreval/dsc/dsc_calibration_fast_neu.py rename to src/nmreval/dsc/dsc_calibration_fast_neu.py diff --git a/nmreval/fit/__init__.py b/src/nmreval/fit/__init__.py similarity index 100% rename from nmreval/fit/__init__.py rename to src/nmreval/fit/__init__.py diff --git a/nmreval/fit/_meta.py b/src/nmreval/fit/_meta.py similarity index 97% rename from nmreval/fit/_meta.py rename to src/nmreval/fit/_meta.py index 68d92bd..e8b101f 100644 --- a/nmreval/fit/_meta.py +++ b/src/nmreval/fit/_meta.py @@ -1,4 +1,6 @@ -from typing import Union, Callable, Any +from __future__ import annotations + +from typing import Callable, Any import operator from inspect import signature, Parameter @@ -44,7 +46,7 @@ class MultiModel: str_op = {'+': operator.add, '*': operator.mul, '-': operator.sub, '/': operator.truediv} int_op = {0: operator.add, 1: operator.mul, 2: operator.sub, 3: operator.truediv} - def __init__(self, left: Any, right: Any, op: Union[str, Callable, int] = '+', left_idx=0, right_idx=1): + def __init__(self, left: Any, right: Any, op: str | Callable | int = '+', left_idx=0, right_idx=1): self._left = left self._right = right diff --git a/nmreval/fit/data.py b/src/nmreval/fit/data.py similarity index 100% rename from nmreval/fit/data.py rename to src/nmreval/fit/data.py diff --git a/nmreval/fit/minimizer.py b/src/nmreval/fit/minimizer.py similarity index 100% rename from nmreval/fit/minimizer.py rename to src/nmreval/fit/minimizer.py index f1dfb4d..bde5a93 100644 --- a/nmreval/fit/minimizer.py +++ b/src/nmreval/fit/minimizer.py @@ -6,9 +6,9 @@ import scipy.linalg as la from scipy import optimize import scipy.odr as odr +from . import EPS from .data import Data from .model import Model -from . import EPS from .parameter import Parameters from .result import FitResultCreator diff --git a/nmreval/fit/model.py b/src/nmreval/fit/model.py similarity index 100% rename from nmreval/fit/model.py rename to src/nmreval/fit/model.py diff --git a/nmreval/fit/parameter.py b/src/nmreval/fit/parameter.py similarity index 100% rename from nmreval/fit/parameter.py rename to src/nmreval/fit/parameter.py diff --git a/nmreval/fit/result.py b/src/nmreval/fit/result.py similarity index 100% rename from nmreval/fit/result.py rename to src/nmreval/fit/result.py index cbcae65..8b705ef 100644 --- a/nmreval/fit/result.py +++ b/src/nmreval/fit/result.py @@ -9,8 +9,8 @@ import numpy as np from scipy.stats import f as fdist from scipy.interpolate import interp1d -from ..data.points import Points from .parameter import Parameter +from ..data.points import Points from ..data.signals import Signal from ..utils.text import convert diff --git a/resources/__init__.py b/src/nmreval/io/__init__.py similarity index 100% rename from resources/__init__.py rename to src/nmreval/io/__init__.py diff --git a/nmreval/io/asciireader.py b/src/nmreval/io/asciireader.py similarity index 100% rename from nmreval/io/asciireader.py rename to src/nmreval/io/asciireader.py diff --git a/nmreval/io/bds_reader.py b/src/nmreval/io/bds_reader.py similarity index 99% rename from nmreval/io/bds_reader.py rename to src/nmreval/io/bds_reader.py index 03a0cef..4ab38fe 100644 --- a/nmreval/io/bds_reader.py +++ b/src/nmreval/io/bds_reader.py @@ -1,8 +1,9 @@ +from __future__ import annotations + import re import struct import warnings from pathlib import Path -from typing import List import numpy as np @@ -117,7 +118,7 @@ class BDSReader: # Z.imag*omega), Z.real, meas.time, meas. temp., ac voltage, dc voltage self.y = np.transpose(_y[:, :, :6], (2, 0, 1)) - def export(self, ymode: str = 'epsilon', xmode: str = 'freq') -> List[BDS]: + def export(self, ymode: str = 'epsilon', xmode: str = 'freq') -> list[BDS]: y = getattr(self, ymode)() useful_info = { diff --git a/nmreval/io/dsc.py b/src/nmreval/io/dsc.py similarity index 99% rename from nmreval/io/dsc.py rename to src/nmreval/io/dsc.py index 2017340..797714c 100644 --- a/nmreval/io/dsc.py +++ b/src/nmreval/io/dsc.py @@ -1,4 +1,5 @@ from __future__ import annotations + from pathlib import Path import re from collections import namedtuple diff --git a/nmreval/io/fcbatchreader.py b/src/nmreval/io/fcbatchreader.py similarity index 77% rename from nmreval/io/fcbatchreader.py rename to src/nmreval/io/fcbatchreader.py index 6e0c1ee..c0da0e0 100644 --- a/nmreval/io/fcbatchreader.py +++ b/src/nmreval/io/fcbatchreader.py @@ -1,19 +1,20 @@ +from __future__ import annotations + import pathlib -from typing import Union import matplotlib.pyplot as plt from scipy.optimize import curve_fit import numpy as np -from ..data.points import Points -from .asciireader import AsciiReader -from .hdfreader import HdfReader -from ..utils.utils import get_temperature, roundrobin +from nmreval.data.points import Points +from nmreval.io.asciireader import AsciiReader +from nmreval.io.hdfreader import HdfReader +from nmreval.utils.utils import get_temperature, roundrobin class FCReader: - def __init__(self, fname: Union[list, str]): - if type(fname) != list: + def __init__(self, fname: (list | str | pathlib.Path)): + if isinstance(fname, (str, pathlib.Path)): self.fnames = [fname] else: self.fnames = fname @@ -24,7 +25,9 @@ class FCReader: self.t_params = {} self.f_params = {} - def __call__(self, fname: Union[list, str]): + self._scipt_type = 'old' + + def __call__(self, fname: (list | str | pathlib.Path)): if isinstance(fname, (str, pathlib.Path)): self.fnames = [fname] else: @@ -71,11 +74,11 @@ class FCReader: continue v.savetxt(save_name) - @staticmethod - def _read_from_hdf(filename: Union[str, pathlib.Path]) -> dict: + def _read_from_hdf(self, filename: (str | pathlib.Path)) -> dict: _temp = {} reader = HdfReader(filename) - for mag in reader.get_selected('mag', dtype='points'): + mag_directory = 'mag' if self._scipt_type == 'old' else 'Magnetization' + for mag in reader.get_selected(mag_directory, dtype='points'): _temp[mag.value] = mag return _temp @@ -197,9 +200,9 @@ class FCReader: fig.savefig(image_path.joinpath(save_name).with_suffix('.png')) plt.close(fig) - freqs = np.array(freqs) - params = np.array(params) - errors = np.array(errors) + freqs = np.asanyarray(freqs) + params = np.asanyarray(params) + errors = np.asanyarray(errors) # das ist jetzt eher haesslich self.t_params[temperature] = np.c_[freqs, @@ -386,3 +389,101 @@ class FCReader: @staticmethod def kww(x, m0, off, t1, beta): return m0 * np.exp(-(x/t1)**beta) + off + + +class FCFileReader: + def __init__(self, fname: str): + self.filename = pathlib.Path(fname) + self._is_dir = self.filename.is_dir() + self._script_type = None + self.reader = None + if not self._is_dir: + self.reader = HdfReader(self.filename) + if 'mag' in self.reader: + self._script_type = 'old' + elif 'Magnetization' in self.reader: + self._script_type = '2022_09' + + self._temperature = get_temperature(self.filename.stem) + + def load_magnetization(self, region=None): + if self._is_dir: + _temp = self._read_from_dir() + + else: + if region is None: + _temp = self._read_from_hdf() + else: + _temp = self._read_signals(region) + + if not _temp: + raise OSError(-666, f'No magnetization found for {self.filename.name}.', self.filename.name) + + + def _read_from_hdf(self) -> dict: + _temp = {} + mag_directory = 'mag' if self._script_type == 'old' else 'Magnetization' + for mag in self.reader.get_selected(mag_directory, dtype='points'): + _temp[mag.value] = mag + + return _temp + + def _read_from_dir(self) -> dict: + fname_no_ext = self.filename.with_suffix('') + data_path = fname_no_ext / 'data' + _temp = {} + + for mag in data_path.glob('*.dat'): + d = AsciiReader(mag).export() + for v in d: + _temp[v.value] = v + break + + return _temp + + def _read_signals(self, region: tuple = None) -> dict: + start = 0 + stop = 30e-5 + + # This is one set with attributes to find default start:stop values + try: + p = self.reader.parameters('/ABS_ACC_FID') + start = p['start'] + stop = p['stop'] + except: + pass + + if region is None: + region = (start, stop) + + if region[0] is None: + region = (start, region[1]) + if region[1] is None: + region = (region[0], stop) + + sig = self.reader.get_selected('/data/B=*/ACC_ABS_FID*', dtype='signal') + _temp = {} + for s in sig: + pts = s.points([region]) + b = s.group + if b not in _temp: + _temp[b] = [] + + _temp[b].append([s.value, *[pp[1] for pp in pts]]) + + for b, m in sorted(_temp.items()): + m = np.array(m) + _temp[b] = Points(x=m[:, 0], y=m[:, 1], value=b, name=f'B={b}').sort() + + return _temp + + + +if __name__ == '__main__': + from pprint import pprint + test = FCReader('/autohome/dominik/nmreval/testdata/fc_test/2022-09-15_1344_new_script.h5') + # test = FCReader('/autohome/dominik/nmreval/testdata/fc_test/314K_2015-09-03_1605.h5') + + test.load_magnetization() + test.load_magnetization(region=(0, 10e-6)) + # pprint(test.data) diff --git a/nmreval/io/graceeditor.py b/src/nmreval/io/graceeditor.py similarity index 99% rename from nmreval/io/graceeditor.py rename to src/nmreval/io/graceeditor.py index 3949929..0f6cb23 100644 --- a/nmreval/io/graceeditor.py +++ b/src/nmreval/io/graceeditor.py @@ -687,10 +687,11 @@ def _convert_to_value(parse_string): for i, v in enumerate(tuples): v = v.strip() - if re.match(r'[+-]?\d+.\d+', v): - tuples[i] = float(v) - elif re.match(r'[+-]?\d+', v): - tuples[i] = int(v) + if re.match(r'[+-]?\d+(?:.\d+)?(?:[Ee][+-]?\d+)?', v): + try: + tuples[i] = int(v) + except ValueError: + tuples[i] = float(v) elif re.match(r'\".*\"', v): tuples[i] = v[1:-1] else: diff --git a/nmreval/io/hdfreader.py b/src/nmreval/io/hdfreader.py similarity index 99% rename from nmreval/io/hdfreader.py rename to src/nmreval/io/hdfreader.py index 2820ef1..ce2d0ef 100644 --- a/nmreval/io/hdfreader.py +++ b/src/nmreval/io/hdfreader.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import re from functools import reduce diff --git a/nmreval/io/merge_agr.py b/src/nmreval/io/merge_agr.py similarity index 99% rename from nmreval/io/merge_agr.py rename to src/nmreval/io/merge_agr.py index ff07088..a97c241 100755 --- a/nmreval/io/merge_agr.py +++ b/src/nmreval/io/merge_agr.py @@ -1,6 +1,5 @@ #! /usr/bin/env python -import sys import re import argparse diff --git a/nmreval/io/nmrreader.py b/src/nmreval/io/nmrreader.py similarity index 96% rename from nmreval/io/nmrreader.py rename to src/nmreval/io/nmrreader.py index 24bd2fe..2268c8c 100644 --- a/nmreval/io/nmrreader.py +++ b/src/nmreval/io/nmrreader.py @@ -1,11 +1,12 @@ +from __future__ import annotations + import pickle from collections import OrderedDict -from typing import Tuple, Union +from .read_old_nmr import HAS_BSDDB3, _read_file_v1 from ..data.nmr import FID, Spectrum from ..data.points import Points from ..fit.result import FitResult, FitResultCreator -from .read_old_nmr import HAS_BSDDB3, _read_file_v1 from ..lib.colors import Colors from ..lib.lines import LineStyle from ..lib.symbols import SymbolStyle @@ -32,7 +33,7 @@ class NMRReader: else: self.version = 2 - def make_data(self, fname: str = None) -> Union[Tuple[dict, dict], Tuple[dict]]: + def make_data(self, fname: str = None) -> tuple[dict, dict] | tuple[dict]: if fname is None: fname = self.filename @@ -43,7 +44,7 @@ class NMRReader: return self._make_new(fname) @staticmethod - def _make_new(fname) -> Tuple[dict, dict]: + def _make_new(fname) -> tuple[dict, dict]: with open(fname, 'rb') as fp: # remove magic _ = fp.read(16) diff --git a/nmreval/io/read_old_nmr.py b/src/nmreval/io/read_old_nmr.py similarity index 100% rename from nmreval/io/read_old_nmr.py rename to src/nmreval/io/read_old_nmr.py diff --git a/nmreval/io/sessionwriter.py b/src/nmreval/io/sessionwriter.py similarity index 100% rename from nmreval/io/sessionwriter.py rename to src/nmreval/io/sessionwriter.py diff --git a/nmreval/io/tntreader.py b/src/nmreval/io/tntreader.py similarity index 100% rename from nmreval/io/tntreader.py rename to src/nmreval/io/tntreader.py diff --git a/resources/icons/__init__.py b/src/nmreval/lib/__init__.py similarity index 100% rename from resources/icons/__init__.py rename to src/nmreval/lib/__init__.py diff --git a/nmreval/lib/colors.py b/src/nmreval/lib/colors.py similarity index 100% rename from nmreval/lib/colors.py rename to src/nmreval/lib/colors.py diff --git a/nmreval/lib/decorator.py b/src/nmreval/lib/decorator.py similarity index 100% rename from nmreval/lib/decorator.py rename to src/nmreval/lib/decorator.py diff --git a/nmreval/lib/importer.py b/src/nmreval/lib/importer.py similarity index 92% rename from nmreval/lib/importer.py rename to src/nmreval/lib/importer.py index e1a426a..3d324fa 100644 --- a/nmreval/lib/importer.py +++ b/src/nmreval/lib/importer.py @@ -1,14 +1,16 @@ +from __future__ import annotations + import inspect import sys + from importlib import reload as import_reload from importlib.util import spec_from_loader, module_from_spec from importlib.machinery import SourceFileLoader from pathlib import Path -from typing import Union -def import_(path: Union[str, Path], reload: bool = False): +def import_(path: str | Path, reload: bool = False): """ Import file from random destination as module """ @@ -44,7 +46,7 @@ def register_mixin(obj, cls): obj.__class__ = type(_obj_cls_name, (_obj_cls, cls), {}) -def reload_(filename: Union[str, Path]): +def reload_(filename: str | Path): return import_(filename, reload=True) diff --git a/nmreval/lib/lines.py b/src/nmreval/lib/lines.py similarity index 100% rename from nmreval/lib/lines.py rename to src/nmreval/lib/lines.py diff --git a/nmreval/lib/logger.py b/src/nmreval/lib/logger.py similarity index 100% rename from nmreval/lib/logger.py rename to src/nmreval/lib/logger.py diff --git a/nmreval/lib/symbols.py b/src/nmreval/lib/symbols.py similarity index 98% rename from nmreval/lib/symbols.py rename to src/nmreval/lib/symbols.py index 2c02a76..a5a9bea 100644 --- a/nmreval/lib/symbols.py +++ b/src/nmreval/lib/symbols.py @@ -1,6 +1,6 @@ import enum -from ..gui_qt.Qt import QtGui, QtCore +from gui_qt.Qt import QtGui, QtCore sym_list = ['o', 's', 'd', 't1', 't3', 't', 't2', '+', 'x', 'star'] diff --git a/nmreval/lib/utils.py b/src/nmreval/lib/utils.py similarity index 100% rename from nmreval/lib/utils.py rename to src/nmreval/lib/utils.py diff --git a/src/nmreval/math/__init__.py b/src/nmreval/math/__init__.py new file mode 100644 index 0000000..31359c6 --- /dev/null +++ b/src/nmreval/math/__init__.py @@ -0,0 +1,32 @@ +""" +=================================== +General maths (:mod:`nmreval.math`) +=================================== + +General maths functions and applications that are not confined to usage with NMR data + +.. currentmodule:: nmreval.math + +.. _apod_functions: + +Apodization functions +************************ + +List of apodization function to make spectra nicer. +All functions are defined in the time domain. + +.. autosummary:: + :toctree: generated/ + :nosignatures: + + apodization.GaussWindow + apodization.ExpWindow + apodization.GaussExpWindow + apodization.Traficante + apodization.Trapezoid + apodization.Trapezoid + apodization.SineBell + apodization.Box + apodization.Hamming + apodization.Hann +""" diff --git a/nmreval/math/apodization.py b/src/nmreval/math/apodization.py similarity index 78% rename from nmreval/math/apodization.py rename to src/nmreval/math/apodization.py index 5bd3901..534da61 100644 --- a/nmreval/math/apodization.py +++ b/src/nmreval/math/apodization.py @@ -1,24 +1,64 @@ +""" +====================== +Apodization functions +====================== +""" + + import numpy as np from scipy.signal.windows import general_hamming class GaussWindow: + r""" + Gaussian function + + .. math:: + y = \exp\Biggl[-\Biggl(\frac{\pi x GB}{4\sqrt{\ln2}}\Biggr)^2\Biggr] + + """ name = 'Gaussian' equation = r'exp(-(\pi GB x/[2*sqrt(ln2)])^{2})' params = ['GB/Hz'] @staticmethod def apod(x, gb): + r""" + Gaussian function + + .. math:: + y = \exp\Biggl[-\Biggl(\frac{\pi x gb}{4\sqrt{\ln2}}\Biggr)^2\Biggr] + + Args: + x (array-like): Input values + gb (float): FWHM (in the frequency domain) + """ return np.exp(-(x*gb*np.pi/4./np.sqrt(np.log(2)))**2) class ExpWindow: + r""" + Exponential function + + .. math:: + y = \exp(-\pi x LB) + """ name = 'Exponential' equation = r'exp(-\pi LB x)' params = ['LB/Hz'] @staticmethod def apod(x, lb): + r""" + Exponential function + + .. math:: + y = \exp(-\pi x lb) + + Args: + x (array-like): Input values + lb (float): FWHM (in the frequency domain) + """ return np.exp(-np.pi*x*lb) diff --git a/nmreval/math/interpol.py b/src/nmreval/math/interpol.py similarity index 100% rename from nmreval/math/interpol.py rename to src/nmreval/math/interpol.py diff --git a/nmreval/math/kww.py b/src/nmreval/math/kww.py similarity index 100% rename from nmreval/math/kww.py rename to src/nmreval/math/kww.py diff --git a/nmreval/math/logfourier.py b/src/nmreval/math/logfourier.py similarity index 100% rename from nmreval/math/logfourier.py rename to src/nmreval/math/logfourier.py diff --git a/nmreval/math/mittagleffler.py b/src/nmreval/math/mittagleffler.py similarity index 98% rename from nmreval/math/mittagleffler.py rename to src/nmreval/math/mittagleffler.py index 874382d..64af143 100644 --- a/nmreval/math/mittagleffler.py +++ b/src/nmreval/math/mittagleffler.py @@ -1,5 +1,7 @@ +from __future__ import annotations + from numbers import Number -from typing import TypeVar, Union +from typing import TypeVar import numpy as np from math import sqrt, log, exp, ceil @@ -39,7 +41,7 @@ def mlf(z: T, a: float, b: float = 1, g: float = 1) -> T: return ret_val.reshape(z.shape) -def _mlf_single(z: Union[int, float, complex], a: float, b: float, g: float): +def _mlf_single(z: int | float | complex, a: float, b: float, g: float): if abs(z) < 1.0e-15: ret_val = 1 / gamma(b) else: diff --git a/nmreval/math/orientations.py b/src/nmreval/math/orientations.py similarity index 100% rename from nmreval/math/orientations.py rename to src/nmreval/math/orientations.py diff --git a/nmreval/math/pca.py b/src/nmreval/math/pca.py similarity index 100% rename from nmreval/math/pca.py rename to src/nmreval/math/pca.py diff --git a/nmreval/math/smooth.py b/src/nmreval/math/smooth.py similarity index 100% rename from nmreval/math/smooth.py rename to src/nmreval/math/smooth.py diff --git a/nmreval/models/__init__.py b/src/nmreval/models/__init__.py similarity index 100% rename from nmreval/models/__init__.py rename to src/nmreval/models/__init__.py diff --git a/nmreval/models/basic.py b/src/nmreval/models/basic.py similarity index 100% rename from nmreval/models/basic.py rename to src/nmreval/models/basic.py diff --git a/nmreval/models/bds.py b/src/nmreval/models/bds.py similarity index 100% rename from nmreval/models/bds.py rename to src/nmreval/models/bds.py diff --git a/nmreval/models/correlationfuncs.py b/src/nmreval/models/correlationfuncs.py similarity index 100% rename from nmreval/models/correlationfuncs.py rename to src/nmreval/models/correlationfuncs.py diff --git a/nmreval/models/diffusion.py b/src/nmreval/models/diffusion.py similarity index 100% rename from nmreval/models/diffusion.py rename to src/nmreval/models/diffusion.py diff --git a/nmreval/models/fieldcycling.py b/src/nmreval/models/fieldcycling.py similarity index 100% rename from nmreval/models/fieldcycling.py rename to src/nmreval/models/fieldcycling.py diff --git a/nmreval/models/relaxation.py b/src/nmreval/models/relaxation.py similarity index 100% rename from nmreval/models/relaxation.py rename to src/nmreval/models/relaxation.py diff --git a/nmreval/models/spectrum.py b/src/nmreval/models/spectrum.py similarity index 97% rename from nmreval/models/spectrum.py rename to src/nmreval/models/spectrum.py index 2a7627f..229cf66 100644 --- a/nmreval/models/spectrum.py +++ b/src/nmreval/models/spectrum.py @@ -1,10 +1,8 @@ -from typing import Union - import numpy as np -__all__ = ['Gaussian', 'Lorentzian', 'PseudoVoigt'] +from ..lib.utils import ArrayLike -ArrayLike = Union[float, np.ndarray] +__all__ = ['Gaussian', 'Lorentzian', 'PseudoVoigt'] class Gaussian: diff --git a/nmreval/models/stimecho.py b/src/nmreval/models/stimecho.py similarity index 100% rename from nmreval/models/stimecho.py rename to src/nmreval/models/stimecho.py index 6c80b7f..26cb111 100644 --- a/nmreval/models/stimecho.py +++ b/src/nmreval/models/stimecho.py @@ -2,8 +2,8 @@ from itertools import product import numpy as np -from ..math.mittagleffler import mlf from .correlationfuncs import GammaCD +from ..math.mittagleffler import mlf class StimEcho: diff --git a/nmreval/models/temperature.py b/src/nmreval/models/temperature.py similarity index 94% rename from nmreval/models/temperature.py rename to src/nmreval/models/temperature.py index cc43777..ff2a12d 100644 --- a/nmreval/models/temperature.py +++ b/src/nmreval/models/temperature.py @@ -3,7 +3,7 @@ import numpy as np from ..utils.constants import kB -class _MAScalibration(object): +class _MAScalibration: type = 'Other' name = 'MAS temperature' equation = '' @@ -15,7 +15,7 @@ class _MAScalibration(object): return 1250 - 3.81194e-6 * np.sqrt(1.47663e17 - 1.32344e14 * realt) -class VFT(object): +class VFT: r""" Calculates Vogel-Fulcher-Tammann @@ -36,7 +36,7 @@ class VFT(object): elif invt == 'invt1000': x = 1000. / x - return t0 * np.exp(b / (x-t0)) + return tau0 * np.exp(b / (x-t0)) class Arrhenius: @@ -57,7 +57,7 @@ class Arrhenius: return tau0 * np.exp(ea / (kB*x)) -class Ecoop(object): +class Ecoop: name = 'Roessler-Ding' type = 'Temperature' equation = r'\tau_{\infty}exp[E_{\infty}/T(1+exp(-\mu((T-T_{A})/E_{\infty})))]' diff --git a/nmreval/models/transitions.py b/src/nmreval/models/transitions.py similarity index 100% rename from nmreval/models/transitions.py rename to src/nmreval/models/transitions.py diff --git a/nmreval/models/usermodels.py b/src/nmreval/models/usermodels.py similarity index 100% rename from nmreval/models/usermodels.py rename to src/nmreval/models/usermodels.py diff --git a/nmreval/models/wideline.py b/src/nmreval/models/wideline.py similarity index 100% rename from nmreval/models/wideline.py rename to src/nmreval/models/wideline.py diff --git a/nmreval/nmr/__init__.py b/src/nmreval/nmr/__init__.py similarity index 100% rename from nmreval/nmr/__init__.py rename to src/nmreval/nmr/__init__.py diff --git a/nmreval/nmr/coupling.py b/src/nmreval/nmr/coupling.py similarity index 100% rename from nmreval/nmr/coupling.py rename to src/nmreval/nmr/coupling.py diff --git a/nmreval/nmr/fc_eval.py b/src/nmreval/nmr/fc_eval.py similarity index 100% rename from nmreval/nmr/fc_eval.py rename to src/nmreval/nmr/fc_eval.py diff --git a/nmreval/nmr/relaxation.py b/src/nmreval/nmr/relaxation.py similarity index 99% rename from nmreval/nmr/relaxation.py rename to src/nmreval/nmr/relaxation.py index fba9ecb..7381316 100755 --- a/nmreval/nmr/relaxation.py +++ b/src/nmreval/nmr/relaxation.py @@ -6,8 +6,7 @@ Classes to calculate spin-lattice and spin-spin relaxation, as well as to evalua """ from __future__ import annotations -from pathlib import Path -from typing import Any, Tuple, Type +from typing import Any, Type from warnings import warn import numpy as np @@ -664,9 +663,9 @@ class RelaxationEvaluation(Relaxation): def calculate_t1_min( self, interpolate: int = None, - trange: Tuple[float, float] = None, + trange: tuple[float, float] = None, use_log: bool = False, - ) -> Tuple[Tuple[float, float], Tuple[np.ndarray, np.ndarray] | None]: + ) -> tuple[tuple[float, float], tuple[np.ndarray, np.ndarray] | None]: """ Determine a minimum position for given T1 data @@ -742,7 +741,7 @@ class RelaxationEvaluation(Relaxation): prefactor: float = None, coupling_param: list = None, coupling_kwargs: dict = None, - ) -> Tuple[np.ndarray, dict]: + ) -> tuple[np.ndarray, dict]: """ Calculate correlation times from set T1 data. Optional arguments overwrite previousliy set parameter. diff --git a/nmreval/utils/__init__.py b/src/nmreval/utils/__init__.py similarity index 100% rename from nmreval/utils/__init__.py rename to src/nmreval/utils/__init__.py diff --git a/nmreval/utils/constants.py b/src/nmreval/utils/constants.py similarity index 100% rename from nmreval/utils/constants.py rename to src/nmreval/utils/constants.py diff --git a/nmreval/utils/exception.py b/src/nmreval/utils/exception.py similarity index 100% rename from nmreval/utils/exception.py rename to src/nmreval/utils/exception.py diff --git a/nmreval/utils/pca_demo_pcs.py b/src/nmreval/utils/pca_demo_pcs.py similarity index 100% rename from nmreval/utils/pca_demo_pcs.py rename to src/nmreval/utils/pca_demo_pcs.py diff --git a/nmreval/utils/pokemon.json b/src/nmreval/utils/pokemon.json similarity index 100% rename from nmreval/utils/pokemon.json rename to src/nmreval/utils/pokemon.json diff --git a/nmreval/utils/text.py b/src/nmreval/utils/text.py similarity index 100% rename from nmreval/utils/text.py rename to src/nmreval/utils/text.py diff --git a/nmreval/utils/utils.py b/src/nmreval/utils/utils.py similarity index 100% rename from nmreval/utils/utils.py rename to src/nmreval/utils/utils.py diff --git a/nmreval/version.py b/src/nmreval/version.py similarity index 100% rename from nmreval/version.py rename to src/nmreval/version.py diff --git a/resources/Default.agr b/src/resources/Default.agr similarity index 100% rename from resources/Default.agr rename to src/resources/Default.agr diff --git a/resources/nmr/__init__.py b/src/resources/__init__.py similarity index 100% rename from resources/nmr/__init__.py rename to src/resources/__init__.py diff --git a/resources/_rc/axes.png b/src/resources/_rc/axes.png similarity index 100% rename from resources/_rc/axes.png rename to src/resources/_rc/axes.png diff --git a/resources/_rc/blackwhite.png b/src/resources/_rc/blackwhite.png similarity index 100% rename from resources/_rc/blackwhite.png rename to src/resources/_rc/blackwhite.png diff --git a/resources/_rc/blackwhite.svg b/src/resources/_rc/blackwhite.svg similarity index 100% rename from resources/_rc/blackwhite.svg rename to src/resources/_rc/blackwhite.svg diff --git a/resources/_rc/cat.png b/src/resources/_rc/cat.png similarity index 100% rename from resources/_rc/cat.png rename to src/resources/_rc/cat.png diff --git a/resources/_rc/colors.png b/src/resources/_rc/colors.png similarity index 100% rename from resources/_rc/colors.png rename to src/resources/_rc/colors.png diff --git a/resources/_rc/colors.svg b/src/resources/_rc/colors.svg similarity index 100% rename from resources/_rc/colors.svg rename to src/resources/_rc/colors.svg diff --git a/resources/_rc/cut_region.png b/src/resources/_rc/cut_region.png similarity index 100% rename from resources/_rc/cut_region.png rename to src/resources/_rc/cut_region.png diff --git a/resources/_rc/eval_button.png b/src/resources/_rc/eval_button.png similarity index 100% rename from resources/_rc/eval_button.png rename to src/resources/_rc/eval_button.png diff --git a/resources/_rc/fit_preview.png b/src/resources/_rc/fit_preview.png similarity index 100% rename from resources/_rc/fit_preview.png rename to src/resources/_rc/fit_preview.png diff --git a/resources/_rc/fit_region.png b/src/resources/_rc/fit_region.png similarity index 100% rename from resources/_rc/fit_region.png rename to src/resources/_rc/fit_region.png diff --git a/resources/_rc/grid.png b/src/resources/_rc/grid.png similarity index 100% rename from resources/_rc/grid.png rename to src/resources/_rc/grid.png diff --git a/resources/_rc/grid.svg b/src/resources/_rc/grid.svg similarity index 100% rename from resources/_rc/grid.svg rename to src/resources/_rc/grid.svg diff --git a/resources/_rc/imag.png b/src/resources/_rc/imag.png similarity index 100% rename from resources/_rc/imag.png rename to src/resources/_rc/imag.png diff --git a/resources/_rc/imag.svg b/src/resources/_rc/imag.svg similarity index 100% rename from resources/_rc/imag.svg rename to src/resources/_rc/imag.svg diff --git a/resources/_rc/images.qrc b/src/resources/_rc/images.qrc similarity index 100% rename from resources/_rc/images.qrc rename to src/resources/_rc/images.qrc diff --git a/resources/_rc/left.png b/src/resources/_rc/left.png similarity index 100% rename from resources/_rc/left.png rename to src/resources/_rc/left.png diff --git a/resources/_rc/logo.png b/src/resources/_rc/logo.png similarity index 100% rename from resources/_rc/logo.png rename to src/resources/_rc/logo.png diff --git a/resources/_rc/mean.png b/src/resources/_rc/mean.png similarity index 100% rename from resources/_rc/mean.png rename to src/resources/_rc/mean.png diff --git a/resources/_rc/mouse.png b/src/resources/_rc/mouse.png similarity index 100% rename from resources/_rc/mouse.png rename to src/resources/_rc/mouse.png diff --git a/resources/_rc/open_session.png b/src/resources/_rc/open_session.png similarity index 100% rename from resources/_rc/open_session.png rename to src/resources/_rc/open_session.png diff --git a/resources/_rc/path48-3-5-6-2.png b/src/resources/_rc/path48-3-5-6-2.png similarity index 100% rename from resources/_rc/path48-3-5-6-2.png rename to src/resources/_rc/path48-3-5-6-2.png diff --git a/resources/_rc/properties.png b/src/resources/_rc/properties.png similarity index 100% rename from resources/_rc/properties.png rename to src/resources/_rc/properties.png diff --git a/resources/_rc/punktdings.png b/src/resources/_rc/punktdings.png similarity index 100% rename from resources/_rc/punktdings.png rename to src/resources/_rc/punktdings.png diff --git a/resources/_rc/real.png b/src/resources/_rc/real.png similarity index 100% rename from resources/_rc/real.png rename to src/resources/_rc/real.png diff --git a/resources/_rc/real.svg b/src/resources/_rc/real.svg similarity index 100% rename from resources/_rc/real.svg rename to src/resources/_rc/real.svg diff --git a/resources/_rc/right.png b/src/resources/_rc/right.png similarity index 100% rename from resources/_rc/right.png rename to src/resources/_rc/right.png diff --git a/resources/_rc/sort.png b/src/resources/_rc/sort.png similarity index 100% rename from resources/_rc/sort.png rename to src/resources/_rc/sort.png diff --git a/resources/_rc/xlog.png b/src/resources/_rc/xlog.png similarity index 100% rename from resources/_rc/xlog.png rename to src/resources/_rc/xlog.png diff --git a/resources/_rc/xlog.svg b/src/resources/_rc/xlog.svg similarity index 100% rename from resources/_rc/xlog.svg rename to src/resources/_rc/xlog.svg diff --git a/resources/_rc/ylog.png b/src/resources/_rc/ylog.png similarity index 100% rename from resources/_rc/ylog.png rename to src/resources/_rc/ylog.png diff --git a/resources/_rc/ylog.svg b/src/resources/_rc/ylog.svg similarity index 100% rename from resources/_rc/ylog.svg rename to src/resources/_rc/ylog.svg diff --git a/resources/_ui/agroptiondialog.ui b/src/resources/_ui/agroptiondialog.ui similarity index 100% rename from resources/_ui/agroptiondialog.ui rename to src/resources/_ui/agroptiondialog.ui diff --git a/resources/_ui/apod_dialog.ui b/src/resources/_ui/apod_dialog.ui similarity index 100% rename from resources/_ui/apod_dialog.ui rename to src/resources/_ui/apod_dialog.ui diff --git a/resources/_ui/asciidialog.ui b/src/resources/_ui/asciidialog.ui similarity index 100% rename from resources/_ui/asciidialog.ui rename to src/resources/_ui/asciidialog.ui diff --git a/resources/_ui/axisConfigTemplate.ui b/src/resources/_ui/axisConfigTemplate.ui similarity index 100% rename from resources/_ui/axisConfigTemplate.ui rename to src/resources/_ui/axisConfigTemplate.ui diff --git a/resources/_ui/baseline_dialog.ui b/src/resources/_ui/baseline_dialog.ui similarity index 100% rename from resources/_ui/baseline_dialog.ui rename to src/resources/_ui/baseline_dialog.ui diff --git a/resources/_ui/basewindow.ui b/src/resources/_ui/basewindow.ui similarity index 100% rename from resources/_ui/basewindow.ui rename to src/resources/_ui/basewindow.ui diff --git a/resources/_ui/bdsdialog.ui b/src/resources/_ui/bdsdialog.ui similarity index 100% rename from resources/_ui/bdsdialog.ui rename to src/resources/_ui/bdsdialog.ui diff --git a/resources/_ui/color_palette.ui b/src/resources/_ui/color_palette.ui similarity index 100% rename from resources/_ui/color_palette.ui rename to src/resources/_ui/color_palette.ui diff --git a/resources/_ui/coupling_calculator.ui b/src/resources/_ui/coupling_calculator.ui similarity index 100% rename from resources/_ui/coupling_calculator.ui rename to src/resources/_ui/coupling_calculator.ui diff --git a/resources/_ui/coupling_t1_from_tau.ui b/src/resources/_ui/coupling_t1_from_tau.ui similarity index 100% rename from resources/_ui/coupling_t1_from_tau.ui rename to src/resources/_ui/coupling_t1_from_tau.ui diff --git a/resources/_ui/datawidget.ui b/src/resources/_ui/datawidget.ui similarity index 100% rename from resources/_ui/datawidget.ui rename to src/resources/_ui/datawidget.ui diff --git a/resources/_ui/dscfile_dialog.ui b/src/resources/_ui/dscfile_dialog.ui similarity index 100% rename from resources/_ui/dscfile_dialog.ui rename to src/resources/_ui/dscfile_dialog.ui diff --git a/resources/_ui/editsignalwidget.ui b/src/resources/_ui/editsignalwidget.ui similarity index 100% rename from resources/_ui/editsignalwidget.ui rename to src/resources/_ui/editsignalwidget.ui diff --git a/resources/_ui/eval_expr_dialog.ui b/src/resources/_ui/eval_expr_dialog.ui similarity index 100% rename from resources/_ui/eval_expr_dialog.ui rename to src/resources/_ui/eval_expr_dialog.ui diff --git a/resources/_ui/evalexpression.ui b/src/resources/_ui/evalexpression.ui similarity index 100% rename from resources/_ui/evalexpression.ui rename to src/resources/_ui/evalexpression.ui diff --git a/resources/_ui/expandablewidget.ui b/src/resources/_ui/expandablewidget.ui similarity index 100% rename from resources/_ui/expandablewidget.ui rename to src/resources/_ui/expandablewidget.ui diff --git a/resources/_ui/exportConfigTemplate.ui b/src/resources/_ui/exportConfigTemplate.ui similarity index 100% rename from resources/_ui/exportConfigTemplate.ui rename to src/resources/_ui/exportConfigTemplate.ui diff --git a/resources/_ui/fcreader.ui b/src/resources/_ui/fcreader.ui similarity index 100% rename from resources/_ui/fcreader.ui rename to src/resources/_ui/fcreader.ui diff --git a/resources/_ui/filedialog.ui b/src/resources/_ui/filedialog.ui similarity index 100% rename from resources/_ui/filedialog.ui rename to src/resources/_ui/filedialog.ui diff --git a/src/resources/_ui/fitcreationdialog.ui b/src/resources/_ui/fitcreationdialog.ui new file mode 100644 index 0000000..f6893a3 --- /dev/null +++ b/src/resources/_ui/fitcreationdialog.ui @@ -0,0 +1,150 @@ + + + Dialog + + + + 0 + 0 + 773 + 633 + + + + + 0 + 0 + + + + Create fit function + + + + + + Qt::Vertical + + + + 0 + + + + Description + + + + 0 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + + Variables + + + + 0 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + + Multiple choice + + + + + + Available Functions + + + + + + + true + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + CodeEditor + QPlainTextEdit +
..lib.codeeditor
+
+
+ + + + buttonBox + accepted() + Dialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Dialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + +
diff --git a/resources/_ui/fitdialog.ui b/src/resources/_ui/fitdialog.ui similarity index 100% rename from resources/_ui/fitdialog.ui rename to src/resources/_ui/fitdialog.ui diff --git a/resources/_ui/fitdialog_window.ui b/src/resources/_ui/fitdialog_window.ui similarity index 100% rename from resources/_ui/fitdialog_window.ui rename to src/resources/_ui/fitdialog_window.ui diff --git a/resources/_ui/fitfunctionwidget.ui b/src/resources/_ui/fitfunctionwidget.ui similarity index 100% rename from resources/_ui/fitfunctionwidget.ui rename to src/resources/_ui/fitfunctionwidget.ui diff --git a/resources/_ui/fitfuncwidget.ui b/src/resources/_ui/fitfuncwidget.ui similarity index 100% rename from resources/_ui/fitfuncwidget.ui rename to src/resources/_ui/fitfuncwidget.ui diff --git a/resources/_ui/fitfuncwidget_old.ui b/src/resources/_ui/fitfuncwidget_old.ui similarity index 100% rename from resources/_ui/fitfuncwidget_old.ui rename to src/resources/_ui/fitfuncwidget_old.ui diff --git a/resources/_ui/fitmodelfixwidget.ui b/src/resources/_ui/fitmodelfixwidget.ui similarity index 100% rename from resources/_ui/fitmodelfixwidget.ui rename to src/resources/_ui/fitmodelfixwidget.ui diff --git a/resources/_ui/fitmodelwidget.ui b/src/resources/_ui/fitmodelwidget.ui similarity index 100% rename from resources/_ui/fitmodelwidget.ui rename to src/resources/_ui/fitmodelwidget.ui diff --git a/resources/_ui/fitparametertable.ui b/src/resources/_ui/fitparametertable.ui similarity index 100% rename from resources/_ui/fitparametertable.ui rename to src/resources/_ui/fitparametertable.ui diff --git a/resources/_ui/fitparameterwidget.ui b/src/resources/_ui/fitparameterwidget.ui similarity index 100% rename from resources/_ui/fitparameterwidget.ui rename to src/resources/_ui/fitparameterwidget.ui diff --git a/resources/_ui/fitresult.ui b/src/resources/_ui/fitresult.ui similarity index 100% rename from resources/_ui/fitresult.ui rename to src/resources/_ui/fitresult.ui diff --git a/resources/_ui/ftdialog.ui b/src/resources/_ui/ftdialog.ui similarity index 100% rename from resources/_ui/ftdialog.ui rename to src/resources/_ui/ftdialog.ui diff --git a/resources/_ui/function_tree_widget.ui b/src/resources/_ui/function_tree_widget.ui similarity index 100% rename from resources/_ui/function_tree_widget.ui rename to src/resources/_ui/function_tree_widget.ui diff --git a/resources/_ui/gol.ui b/src/resources/_ui/gol.ui similarity index 100% rename from resources/_ui/gol.ui rename to src/resources/_ui/gol.ui diff --git a/resources/_ui/gracemsgdialog.ui b/src/resources/_ui/gracemsgdialog.ui similarity index 100% rename from resources/_ui/gracemsgdialog.ui rename to src/resources/_ui/gracemsgdialog.ui diff --git a/resources/_ui/gracereader.ui b/src/resources/_ui/gracereader.ui similarity index 100% rename from resources/_ui/gracereader.ui rename to src/resources/_ui/gracereader.ui diff --git a/resources/_ui/graph.ui b/src/resources/_ui/graph.ui similarity index 100% rename from resources/_ui/graph.ui rename to src/resources/_ui/graph.ui diff --git a/resources/_ui/guidelinewidget.ui b/src/resources/_ui/guidelinewidget.ui similarity index 100% rename from resources/_ui/guidelinewidget.ui rename to src/resources/_ui/guidelinewidget.ui diff --git a/resources/_ui/hdftree.ui b/src/resources/_ui/hdftree.ui similarity index 100% rename from resources/_ui/hdftree.ui rename to src/resources/_ui/hdftree.ui diff --git a/resources/_ui/integral_widget.ui b/src/resources/_ui/integral_widget.ui similarity index 100% rename from resources/_ui/integral_widget.ui rename to src/resources/_ui/integral_widget.ui diff --git a/resources/_ui/integratederive_dialog.ui b/src/resources/_ui/integratederive_dialog.ui similarity index 100% rename from resources/_ui/integratederive_dialog.ui rename to src/resources/_ui/integratederive_dialog.ui diff --git a/resources/_ui/interpol_dialog.ui b/src/resources/_ui/interpol_dialog.ui similarity index 100% rename from resources/_ui/interpol_dialog.ui rename to src/resources/_ui/interpol_dialog.ui diff --git a/resources/_ui/lineedit_dialog.ui b/src/resources/_ui/lineedit_dialog.ui similarity index 100% rename from resources/_ui/lineedit_dialog.ui rename to src/resources/_ui/lineedit_dialog.ui diff --git a/resources/_ui/mean_form.ui b/src/resources/_ui/mean_form.ui similarity index 100% rename from resources/_ui/mean_form.ui rename to src/resources/_ui/mean_form.ui diff --git a/resources/_ui/meandialog.ui b/src/resources/_ui/meandialog.ui similarity index 100% rename from resources/_ui/meandialog.ui rename to src/resources/_ui/meandialog.ui diff --git a/resources/_ui/modelwidget.ui b/src/resources/_ui/modelwidget.ui similarity index 100% rename from resources/_ui/modelwidget.ui rename to src/resources/_ui/modelwidget.ui diff --git a/resources/_ui/move_dialog.ui b/src/resources/_ui/move_dialog.ui similarity index 100% rename from resources/_ui/move_dialog.ui rename to src/resources/_ui/move_dialog.ui diff --git a/resources/_ui/namespace_widget.ui b/src/resources/_ui/namespace_widget.ui similarity index 100% rename from resources/_ui/namespace_widget.ui rename to src/resources/_ui/namespace_widget.ui diff --git a/resources/_ui/option_selection.ui b/src/resources/_ui/option_selection.ui similarity index 100% rename from resources/_ui/option_selection.ui rename to src/resources/_ui/option_selection.ui diff --git a/resources/_ui/parameterform.ui b/src/resources/_ui/parameterform.ui similarity index 100% rename from resources/_ui/parameterform.ui rename to src/resources/_ui/parameterform.ui diff --git a/resources/_ui/phase_corr_dialog.ui b/src/resources/_ui/phase_corr_dialog.ui similarity index 100% rename from resources/_ui/phase_corr_dialog.ui rename to src/resources/_ui/phase_corr_dialog.ui diff --git a/resources/_ui/plotConfigTemplate.ui b/src/resources/_ui/plotConfigTemplate.ui similarity index 100% rename from resources/_ui/plotConfigTemplate.ui rename to src/resources/_ui/plotConfigTemplate.ui diff --git a/resources/_ui/pokemon.ui b/src/resources/_ui/pokemon.ui similarity index 100% rename from resources/_ui/pokemon.ui rename to src/resources/_ui/pokemon.ui diff --git a/resources/_ui/propwidget.ui b/src/resources/_ui/propwidget.ui similarity index 100% rename from resources/_ui/propwidget.ui rename to src/resources/_ui/propwidget.ui diff --git a/resources/_ui/ptstab.ui b/src/resources/_ui/ptstab.ui similarity index 100% rename from resources/_ui/ptstab.ui rename to src/resources/_ui/ptstab.ui diff --git a/resources/_ui/qfiledialog.ui b/src/resources/_ui/qfiledialog.ui similarity index 100% rename from resources/_ui/qfiledialog.ui rename to src/resources/_ui/qfiledialog.ui diff --git a/resources/_ui/save_fit_parameter.ui b/src/resources/_ui/save_fit_parameter.ui similarity index 100% rename from resources/_ui/save_fit_parameter.ui rename to src/resources/_ui/save_fit_parameter.ui diff --git a/resources/_ui/save_fitmodel_dialog.ui b/src/resources/_ui/save_fitmodel_dialog.ui similarity index 100% rename from resources/_ui/save_fitmodel_dialog.ui rename to src/resources/_ui/save_fitmodel_dialog.ui diff --git a/resources/_ui/save_options.ui b/src/resources/_ui/save_options.ui similarity index 100% rename from resources/_ui/save_options.ui rename to src/resources/_ui/save_options.ui diff --git a/resources/_ui/saveoptions.ui b/src/resources/_ui/saveoptions.ui similarity index 100% rename from resources/_ui/saveoptions.ui rename to src/resources/_ui/saveoptions.ui diff --git a/resources/_ui/sdmodelwidget.ui b/src/resources/_ui/sdmodelwidget.ui similarity index 100% rename from resources/_ui/sdmodelwidget.ui rename to src/resources/_ui/sdmodelwidget.ui diff --git a/resources/_ui/selection_widget.ui b/src/resources/_ui/selection_widget.ui similarity index 100% rename from resources/_ui/selection_widget.ui rename to src/resources/_ui/selection_widget.ui diff --git a/resources/_ui/setbyfunction_dialog.ui b/src/resources/_ui/setbyfunction_dialog.ui similarity index 100% rename from resources/_ui/setbyfunction_dialog.ui rename to src/resources/_ui/setbyfunction_dialog.ui diff --git a/resources/_ui/shift_scale_dialog.ui b/src/resources/_ui/shift_scale_dialog.ui similarity index 99% rename from resources/_ui/shift_scale_dialog.ui rename to src/resources/_ui/shift_scale_dialog.ui index a3ac3a8..6f7939b 100644 --- a/resources/_ui/shift_scale_dialog.ui +++ b/src/resources/_ui/shift_scale_dialog.ui @@ -510,7 +510,7 @@ SciSpinBox QDoubleSpinBox -
..lib.utils
+
..lib.spinboxes
diff --git a/resources/_ui/skipdialog.ui b/src/resources/_ui/skipdialog.ui similarity index 100% rename from resources/_ui/skipdialog.ui rename to src/resources/_ui/skipdialog.ui diff --git a/resources/_ui/smoothdialog.ui b/src/resources/_ui/smoothdialog.ui similarity index 100% rename from resources/_ui/smoothdialog.ui rename to src/resources/_ui/smoothdialog.ui diff --git a/resources/_ui/t1_calc_dialog.ui b/src/resources/_ui/t1_calc_dialog.ui similarity index 100% rename from resources/_ui/t1_calc_dialog.ui rename to src/resources/_ui/t1_calc_dialog.ui diff --git a/resources/_ui/t1_dock.ui b/src/resources/_ui/t1_dock.ui similarity index 100% rename from resources/_ui/t1_dock.ui rename to src/resources/_ui/t1_dock.ui diff --git a/resources/_ui/t1_tau_calculation.ui b/src/resources/_ui/t1_tau_calculation.ui similarity index 100% rename from resources/_ui/t1_tau_calculation.ui rename to src/resources/_ui/t1_tau_calculation.ui diff --git a/resources/_ui/t1dialog.ui b/src/resources/_ui/t1dialog.ui similarity index 100% rename from resources/_ui/t1dialog.ui rename to src/resources/_ui/t1dialog.ui diff --git a/resources/_ui/tntdialog.ui b/src/resources/_ui/tntdialog.ui similarity index 100% rename from resources/_ui/tntdialog.ui rename to src/resources/_ui/tntdialog.ui diff --git a/resources/_ui/typeconversion.ui b/src/resources/_ui/typeconversion.ui similarity index 100% rename from resources/_ui/typeconversion.ui rename to src/resources/_ui/typeconversion.ui diff --git a/resources/_ui/untitled.ui b/src/resources/_ui/untitled.ui similarity index 100% rename from resources/_ui/untitled.ui rename to src/resources/_ui/untitled.ui diff --git a/resources/_ui/userfitassist.ui b/src/resources/_ui/userfitassist.ui similarity index 100% rename from resources/_ui/userfitassist.ui rename to src/resources/_ui/userfitassist.ui diff --git a/resources/_ui/usermodeleditor.ui b/src/resources/_ui/usermodeleditor.ui similarity index 100% rename from resources/_ui/usermodeleditor.ui rename to src/resources/_ui/usermodeleditor.ui diff --git a/resources/_ui/valueeditor.ui b/src/resources/_ui/valueeditor.ui similarity index 100% rename from resources/_ui/valueeditor.ui rename to src/resources/_ui/valueeditor.ui diff --git a/src/resources/icons/__init__.py b/src/resources/icons/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/resources/icons/icons.json b/src/resources/icons/icons.json similarity index 100% rename from resources/icons/icons.json rename to src/resources/icons/icons.json diff --git a/resources/icons/logo.png b/src/resources/icons/logo.png similarity index 100% rename from resources/icons/logo.png rename to src/resources/icons/logo.png diff --git a/resources/icons/normal_light/__init__.py b/src/resources/icons/normal_light/__init__.py similarity index 100% rename from resources/icons/normal_light/__init__.py rename to src/resources/icons/normal_light/__init__.py diff --git a/resources/icons/normal_light/blackwhite.png b/src/resources/icons/normal_light/blackwhite.png similarity index 100% rename from resources/icons/normal_light/blackwhite.png rename to src/resources/icons/normal_light/blackwhite.png diff --git a/resources/icons/normal_light/colors.png b/src/resources/icons/normal_light/colors.png similarity index 100% rename from resources/icons/normal_light/colors.png rename to src/resources/icons/normal_light/colors.png diff --git a/resources/icons/normal_light/concat.png b/src/resources/icons/normal_light/concat.png similarity index 100% rename from resources/icons/normal_light/concat.png rename to src/resources/icons/normal_light/concat.png diff --git a/resources/icons/normal_light/errors.png b/src/resources/icons/normal_light/errors.png similarity index 100% rename from resources/icons/normal_light/errors.png rename to src/resources/icons/normal_light/errors.png diff --git a/resources/icons/normal_light/eval_expression.png b/src/resources/icons/normal_light/eval_expression.png similarity index 100% rename from resources/icons/normal_light/eval_expression.png rename to src/resources/icons/normal_light/eval_expression.png diff --git a/resources/icons/normal_light/fit.png b/src/resources/icons/normal_light/fit.png similarity index 100% rename from resources/icons/normal_light/fit.png rename to src/resources/icons/normal_light/fit.png diff --git a/resources/icons/normal_light/fit_region.png b/src/resources/icons/normal_light/fit_region.png similarity index 100% rename from resources/icons/normal_light/fit_region.png rename to src/resources/icons/normal_light/fit_region.png diff --git a/resources/icons/normal_light/geteilt_icon.png b/src/resources/icons/normal_light/geteilt_icon.png similarity index 100% rename from resources/icons/normal_light/geteilt_icon.png rename to src/resources/icons/normal_light/geteilt_icon.png diff --git a/resources/icons/normal_light/grid.png b/src/resources/icons/normal_light/grid.png similarity index 100% rename from resources/icons/normal_light/grid.png rename to src/resources/icons/normal_light/grid.png diff --git a/resources/icons/normal_light/imag.png b/src/resources/icons/normal_light/imag.png similarity index 100% rename from resources/icons/normal_light/imag.png rename to src/resources/icons/normal_light/imag.png diff --git a/resources/icons/normal_light/left.png b/src/resources/icons/normal_light/left.png similarity index 100% rename from resources/icons/normal_light/left.png rename to src/resources/icons/normal_light/left.png diff --git a/resources/icons/normal_light/legend.png b/src/resources/icons/normal_light/legend.png similarity index 100% rename from resources/icons/normal_light/legend.png rename to src/resources/icons/normal_light/legend.png diff --git a/resources/icons/normal_light/mal_icon.png b/src/resources/icons/normal_light/mal_icon.png similarity index 100% rename from resources/icons/normal_light/mal_icon.png rename to src/resources/icons/normal_light/mal_icon.png diff --git a/resources/icons/normal_light/mean.png b/src/resources/icons/normal_light/mean.png similarity index 100% rename from resources/icons/normal_light/mean.png rename to src/resources/icons/normal_light/mean.png diff --git a/resources/icons/normal_light/messdings.png b/src/resources/icons/normal_light/messdings.png similarity index 100% rename from resources/icons/normal_light/messdings.png rename to src/resources/icons/normal_light/messdings.png diff --git a/resources/icons/normal_light/minus_icon.png b/src/resources/icons/normal_light/minus_icon.png similarity index 100% rename from resources/icons/normal_light/minus_icon.png rename to src/resources/icons/normal_light/minus_icon.png diff --git a/resources/icons/normal_light/mouse.png b/src/resources/icons/normal_light/mouse.png similarity index 100% rename from resources/icons/normal_light/mouse.png rename to src/resources/icons/normal_light/mouse.png diff --git a/resources/icons/normal_light/new.png b/src/resources/icons/normal_light/new.png similarity index 100% rename from resources/icons/normal_light/new.png rename to src/resources/icons/normal_light/new.png diff --git a/resources/icons/normal_light/normal.png b/src/resources/icons/normal_light/normal.png similarity index 100% rename from resources/icons/normal_light/normal.png rename to src/resources/icons/normal_light/normal.png diff --git a/resources/icons/normal_light/open.png b/src/resources/icons/normal_light/open.png similarity index 100% rename from resources/icons/normal_light/open.png rename to src/resources/icons/normal_light/open.png diff --git a/resources/icons/normal_light/plus.png b/src/resources/icons/normal_light/plus.png similarity index 100% rename from resources/icons/normal_light/plus.png rename to src/resources/icons/normal_light/plus.png diff --git a/resources/icons/normal_light/plus_icon.png b/src/resources/icons/normal_light/plus_icon.png similarity index 100% rename from resources/icons/normal_light/plus_icon.png rename to src/resources/icons/normal_light/plus_icon.png diff --git a/resources/icons/normal_light/points_pick.png b/src/resources/icons/normal_light/points_pick.png similarity index 100% rename from resources/icons/normal_light/points_pick.png rename to src/resources/icons/normal_light/points_pick.png diff --git a/resources/icons/normal_light/real.png b/src/resources/icons/normal_light/real.png similarity index 100% rename from resources/icons/normal_light/real.png rename to src/resources/icons/normal_light/real.png diff --git a/resources/icons/normal_light/right.png b/src/resources/icons/normal_light/right.png similarity index 100% rename from resources/icons/normal_light/right.png rename to src/resources/icons/normal_light/right.png diff --git a/resources/icons/normal_light/save.png b/src/resources/icons/normal_light/save.png similarity index 100% rename from resources/icons/normal_light/save.png rename to src/resources/icons/normal_light/save.png diff --git a/resources/icons/normal_light/save_session.png b/src/resources/icons/normal_light/save_session.png similarity index 100% rename from resources/icons/normal_light/save_session.png rename to src/resources/icons/normal_light/save_session.png diff --git a/resources/icons/normal_light/scaling.png b/src/resources/icons/normal_light/scaling.png similarity index 100% rename from resources/icons/normal_light/scaling.png rename to src/resources/icons/normal_light/scaling.png diff --git a/resources/icons/normal_light/sort.png b/src/resources/icons/normal_light/sort.png similarity index 100% rename from resources/icons/normal_light/sort.png rename to src/resources/icons/normal_light/sort.png diff --git a/resources/icons/normal_light/t1_from_tau.png b/src/resources/icons/normal_light/t1_from_tau.png similarity index 100% rename from resources/icons/normal_light/t1_from_tau.png rename to src/resources/icons/normal_light/t1_from_tau.png diff --git a/resources/icons/normal_light/tau_from_t1.png b/src/resources/icons/normal_light/tau_from_t1.png similarity index 100% rename from resources/icons/normal_light/tau_from_t1.png rename to src/resources/icons/normal_light/tau_from_t1.png diff --git a/resources/icons/normal_light/values.png b/src/resources/icons/normal_light/values.png similarity index 100% rename from resources/icons/normal_light/values.png rename to src/resources/icons/normal_light/values.png diff --git a/resources/icons/normal_light/xlog.png b/src/resources/icons/normal_light/xlog.png similarity index 100% rename from resources/icons/normal_light/xlog.png rename to src/resources/icons/normal_light/xlog.png diff --git a/resources/icons/normal_light/ylog.png b/src/resources/icons/normal_light/ylog.png similarity index 100% rename from resources/icons/normal_light/ylog.png rename to src/resources/icons/normal_light/ylog.png diff --git a/resources/icons/pokemon_light/__init__.py b/src/resources/icons/pokemon_light/__init__.py similarity index 100% rename from resources/icons/pokemon_light/__init__.py rename to src/resources/icons/pokemon_light/__init__.py diff --git a/resources/icons/pokemon_light/blackwhite.png b/src/resources/icons/pokemon_light/blackwhite.png similarity index 100% rename from resources/icons/pokemon_light/blackwhite.png rename to src/resources/icons/pokemon_light/blackwhite.png diff --git a/resources/icons/pokemon_light/colors.png b/src/resources/icons/pokemon_light/colors.png similarity index 100% rename from resources/icons/pokemon_light/colors.png rename to src/resources/icons/pokemon_light/colors.png diff --git a/resources/icons/pokemon_light/concat.png b/src/resources/icons/pokemon_light/concat.png similarity index 100% rename from resources/icons/pokemon_light/concat.png rename to src/resources/icons/pokemon_light/concat.png diff --git a/resources/icons/pokemon_light/errors.png b/src/resources/icons/pokemon_light/errors.png similarity index 100% rename from resources/icons/pokemon_light/errors.png rename to src/resources/icons/pokemon_light/errors.png diff --git a/resources/icons/pokemon_light/eval_expression.png b/src/resources/icons/pokemon_light/eval_expression.png similarity index 100% rename from resources/icons/pokemon_light/eval_expression.png rename to src/resources/icons/pokemon_light/eval_expression.png diff --git a/resources/icons/pokemon_light/fit.png b/src/resources/icons/pokemon_light/fit.png similarity index 100% rename from resources/icons/pokemon_light/fit.png rename to src/resources/icons/pokemon_light/fit.png diff --git a/resources/icons/pokemon_light/fit_region.png b/src/resources/icons/pokemon_light/fit_region.png similarity index 100% rename from resources/icons/pokemon_light/fit_region.png rename to src/resources/icons/pokemon_light/fit_region.png diff --git a/resources/icons/pokemon_light/geteilt_icon.png b/src/resources/icons/pokemon_light/geteilt_icon.png similarity index 100% rename from resources/icons/pokemon_light/geteilt_icon.png rename to src/resources/icons/pokemon_light/geteilt_icon.png diff --git a/resources/icons/pokemon_light/grid.png b/src/resources/icons/pokemon_light/grid.png similarity index 100% rename from resources/icons/pokemon_light/grid.png rename to src/resources/icons/pokemon_light/grid.png diff --git a/resources/icons/pokemon_light/imag.png b/src/resources/icons/pokemon_light/imag.png similarity index 100% rename from resources/icons/pokemon_light/imag.png rename to src/resources/icons/pokemon_light/imag.png diff --git a/resources/icons/pokemon_light/left.png b/src/resources/icons/pokemon_light/left.png similarity index 100% rename from resources/icons/pokemon_light/left.png rename to src/resources/icons/pokemon_light/left.png diff --git a/resources/icons/pokemon_light/legend.png b/src/resources/icons/pokemon_light/legend.png similarity index 100% rename from resources/icons/pokemon_light/legend.png rename to src/resources/icons/pokemon_light/legend.png diff --git a/resources/icons/pokemon_light/mal_icon.png b/src/resources/icons/pokemon_light/mal_icon.png similarity index 100% rename from resources/icons/pokemon_light/mal_icon.png rename to src/resources/icons/pokemon_light/mal_icon.png diff --git a/resources/icons/pokemon_light/mean.png b/src/resources/icons/pokemon_light/mean.png similarity index 100% rename from resources/icons/pokemon_light/mean.png rename to src/resources/icons/pokemon_light/mean.png diff --git a/resources/icons/pokemon_light/messdings.png b/src/resources/icons/pokemon_light/messdings.png similarity index 100% rename from resources/icons/pokemon_light/messdings.png rename to src/resources/icons/pokemon_light/messdings.png diff --git a/resources/icons/pokemon_light/minus_icon.png b/src/resources/icons/pokemon_light/minus_icon.png similarity index 100% rename from resources/icons/pokemon_light/minus_icon.png rename to src/resources/icons/pokemon_light/minus_icon.png diff --git a/resources/icons/pokemon_light/mouse.png b/src/resources/icons/pokemon_light/mouse.png similarity index 100% rename from resources/icons/pokemon_light/mouse.png rename to src/resources/icons/pokemon_light/mouse.png diff --git a/resources/icons/pokemon_light/new.png b/src/resources/icons/pokemon_light/new.png similarity index 100% rename from resources/icons/pokemon_light/new.png rename to src/resources/icons/pokemon_light/new.png diff --git a/resources/icons/pokemon_light/normal.png b/src/resources/icons/pokemon_light/normal.png similarity index 100% rename from resources/icons/pokemon_light/normal.png rename to src/resources/icons/pokemon_light/normal.png diff --git a/resources/icons/pokemon_light/open.png b/src/resources/icons/pokemon_light/open.png similarity index 100% rename from resources/icons/pokemon_light/open.png rename to src/resources/icons/pokemon_light/open.png diff --git a/resources/icons/pokemon_light/plus.png b/src/resources/icons/pokemon_light/plus.png similarity index 100% rename from resources/icons/pokemon_light/plus.png rename to src/resources/icons/pokemon_light/plus.png diff --git a/resources/icons/pokemon_light/plus_icon.png b/src/resources/icons/pokemon_light/plus_icon.png similarity index 100% rename from resources/icons/pokemon_light/plus_icon.png rename to src/resources/icons/pokemon_light/plus_icon.png diff --git a/resources/icons/pokemon_light/points_pick.png b/src/resources/icons/pokemon_light/points_pick.png similarity index 100% rename from resources/icons/pokemon_light/points_pick.png rename to src/resources/icons/pokemon_light/points_pick.png diff --git a/resources/icons/pokemon_light/real.png b/src/resources/icons/pokemon_light/real.png similarity index 100% rename from resources/icons/pokemon_light/real.png rename to src/resources/icons/pokemon_light/real.png diff --git a/resources/icons/pokemon_light/right.png b/src/resources/icons/pokemon_light/right.png similarity index 100% rename from resources/icons/pokemon_light/right.png rename to src/resources/icons/pokemon_light/right.png diff --git a/resources/icons/pokemon_light/save.png b/src/resources/icons/pokemon_light/save.png similarity index 100% rename from resources/icons/pokemon_light/save.png rename to src/resources/icons/pokemon_light/save.png diff --git a/resources/icons/pokemon_light/save_session.png b/src/resources/icons/pokemon_light/save_session.png similarity index 100% rename from resources/icons/pokemon_light/save_session.png rename to src/resources/icons/pokemon_light/save_session.png diff --git a/resources/icons/pokemon_light/scaling.png b/src/resources/icons/pokemon_light/scaling.png similarity index 100% rename from resources/icons/pokemon_light/scaling.png rename to src/resources/icons/pokemon_light/scaling.png diff --git a/resources/icons/pokemon_light/sort.png b/src/resources/icons/pokemon_light/sort.png similarity index 100% rename from resources/icons/pokemon_light/sort.png rename to src/resources/icons/pokemon_light/sort.png diff --git a/resources/icons/pokemon_light/t1_from_tau.png b/src/resources/icons/pokemon_light/t1_from_tau.png similarity index 100% rename from resources/icons/pokemon_light/t1_from_tau.png rename to src/resources/icons/pokemon_light/t1_from_tau.png diff --git a/resources/icons/pokemon_light/tau_from_t1.png b/src/resources/icons/pokemon_light/tau_from_t1.png similarity index 100% rename from resources/icons/pokemon_light/tau_from_t1.png rename to src/resources/icons/pokemon_light/tau_from_t1.png diff --git a/resources/icons/pokemon_light/values.png b/src/resources/icons/pokemon_light/values.png similarity index 100% rename from resources/icons/pokemon_light/values.png rename to src/resources/icons/pokemon_light/values.png diff --git a/resources/icons/pokemon_light/xlog.png b/src/resources/icons/pokemon_light/xlog.png similarity index 100% rename from resources/icons/pokemon_light/xlog.png rename to src/resources/icons/pokemon_light/xlog.png diff --git a/resources/icons/pokemon_light/ylog.png b/src/resources/icons/pokemon_light/ylog.png similarity index 100% rename from resources/icons/pokemon_light/ylog.png rename to src/resources/icons/pokemon_light/ylog.png diff --git a/resources/icons/style.qss b/src/resources/icons/style.qss similarity index 100% rename from resources/icons/style.qss rename to src/resources/icons/style.qss diff --git a/resources/logo.png b/src/resources/logo.png similarity index 100% rename from resources/logo.png rename to src/resources/logo.png diff --git a/resources/nmr/Cole-Cole_min.dat b/src/resources/nmr/Cole-Cole_min.dat similarity index 100% rename from resources/nmr/Cole-Cole_min.dat rename to src/resources/nmr/Cole-Cole_min.dat diff --git a/resources/nmr/Cole-Davidson_min.dat b/src/resources/nmr/Cole-Davidson_min.dat similarity index 100% rename from resources/nmr/Cole-Davidson_min.dat rename to src/resources/nmr/Cole-Davidson_min.dat diff --git a/resources/nmr/KWW_min.dat b/src/resources/nmr/KWW_min.dat similarity index 100% rename from resources/nmr/KWW_min.dat rename to src/resources/nmr/KWW_min.dat diff --git a/resources/nmr/Log-Gaussian_min.dat b/src/resources/nmr/Log-Gaussian_min.dat similarity index 100% rename from resources/nmr/Log-Gaussian_min.dat rename to src/resources/nmr/Log-Gaussian_min.dat diff --git a/resources/nmr/T1_min.npz b/src/resources/nmr/T1_min.npz similarity index 100% rename from resources/nmr/T1_min.npz rename to src/resources/nmr/T1_min.npz diff --git a/src/resources/nmr/__init__.py b/src/resources/nmr/__init__.py new file mode 100644 index 0000000..e69de29