From f7bdc2acff3c13a6d632c28c4569690ab106eed7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Picca=20Fr=C3=A9d=C3=A9ric-Emmanuel?= Date: Fri, 18 Aug 2017 14:48:52 +0200 Subject: Import Upstream version 0.5.0+dfsg --- doc/source/Tutorials/Sift/sift.rst | 315 ++++++++++ doc/source/Tutorials/array_widget.rst | 246 ++++++++ doc/source/Tutorials/fit.rst | 635 +++++++++++++++++++++ doc/source/Tutorials/fitconfig.rst | 207 +++++++ doc/source/Tutorials/img/arraywidget3D_0.png | Bin 0 -> 35724 bytes doc/source/Tutorials/img/arraywidget3D_1.png | Bin 0 -> 23956 bytes doc/source/Tutorials/img/arraywidget5D_0.png | Bin 0 -> 34473 bytes doc/source/Tutorials/img/arraywidget5D_1.png | Bin 0 -> 24553 bytes .../Tutorials/img/custom_config_scale0.5.png | Bin 0 -> 186529 bytes .../Tutorials/img/custom_config_scale1.0.png | Bin 0 -> 181099 bytes .../Tutorials/img/custom_config_scale2.1.png | Bin 0 -> 183066 bytes doc/source/Tutorials/img/fitwidget1.png | Bin 0 -> 31627 bytes doc/source/Tutorials/img/fitwidget2.png | Bin 0 -> 106983 bytes doc/source/Tutorials/img/fitwidget3.png | Bin 0 -> 26141 bytes doc/source/Tutorials/img/fitwidget4.png | Bin 0 -> 121846 bytes doc/source/Tutorials/img/fitwidget5.png | Bin 0 -> 29784 bytes doc/source/Tutorials/img/stripbg_plot1.png | Bin 0 -> 41420 bytes doc/source/Tutorials/img/stripbg_plot2.png | Bin 0 -> 45619 bytes doc/source/Tutorials/specfile_to_hdf5.rst | 323 +++++++++++ doc/source/changelog.rst | 1 + doc/source/conf.py | 255 +++++++++ doc/source/description/img/sift_bench_cpu0.png | Bin 0 -> 43625 bytes doc/source/description/img/sift_bench_cpu_kp.png | Bin 0 -> 29356 bytes doc/source/description/img/sift_bench_cpu_res.png | Bin 0 -> 27730 bytes doc/source/description/img/sift_bench_gpu0.png | Bin 0 -> 44086 bytes doc/source/description/img/sift_bench_gpu_kp.png | Bin 0 -> 28994 bytes doc/source/description/img/sift_bench_gpu_res.png | Bin 0 -> 30067 bytes doc/source/description/img/sift_dog1.png | Bin 0 -> 53704 bytes doc/source/description/img/sift_match1.png | Bin 0 -> 210886 bytes doc/source/description/img/sift_orientation.png | Bin 0 -> 34425 bytes doc/source/description/index.rst | 9 + doc/source/description/sift.rst | 399 +++++++++++++ doc/source/img/silx.ico | Bin 0 -> 4286 bytes doc/source/img/silx_large.png | Bin 0 -> 293645 bytes doc/source/img/silx_small.png | Bin 0 -> 9002 bytes doc/source/index.rst | 47 ++ doc/source/install.rst | 306 ++++++++++ doc/source/license.rst | 10 + doc/source/modules/gui/console.rst | 9 + doc/source/modules/gui/data/arraytable.rst | 23 + doc/source/modules/gui/data/dataviewer.rst | 7 + doc/source/modules/gui/data/dataviewerframe.rst | 7 + doc/source/modules/gui/data/img/DataViewer.png | Bin 0 -> 37627 bytes .../modules/gui/data/img/DataViewerFrame.png | Bin 0 -> 41699 bytes .../modules/gui/data/img/NumpyAxesSelector.png | Bin 0 -> 9537 bytes doc/source/modules/gui/data/index.rst | 19 + doc/source/modules/gui/data/numpyaxesselector.rst | 7 + doc/source/modules/gui/data/textformatter.rst | 7 + doc/source/modules/gui/designer.rst | 1 + doc/source/modules/gui/fit/backgroundwidget.rst | 27 + doc/source/modules/gui/fit/fitwidget.rst | 18 + doc/source/modules/gui/fit/img/bgwidget.png | Bin 0 -> 68544 bytes doc/source/modules/gui/fit/index.rst | 32 ++ .../modules/gui/hdf5/examples_hdf5widget.rst | 6 + doc/source/modules/gui/hdf5/getting_started.rst | 226 ++++++++ doc/source/modules/gui/hdf5/h5node.rst | 9 + .../modules/gui/hdf5/hdf5contextmenuevent.rst | 9 + doc/source/modules/gui/hdf5/hdf5treemodel.rst | 9 + doc/source/modules/gui/hdf5/hdf5treeview.rst | 9 + doc/source/modules/gui/hdf5/img/Hdf5Example.png | Bin 0 -> 98584 bytes doc/source/modules/gui/hdf5/img/Hdf5TreeView.png | Bin 0 -> 38565 bytes doc/source/modules/gui/hdf5/index.rst | 46 ++ .../modules/gui/hdf5/nexussortfilterproxymodel.rst | 9 + doc/source/modules/gui/icons.rst | 346 +++++++++++ doc/source/modules/gui/index.rst | 21 + doc/source/modules/gui/plot/dev.rst | 204 +++++++ doc/source/modules/gui/plot/getting_started.rst | 491 ++++++++++++++++ doc/source/modules/gui/plot/imageview.rst | 15 + doc/source/modules/gui/plot/img/ImageView.png | Bin 0 -> 174050 bytes doc/source/modules/gui/plot/img/LimitsToolBar.png | Bin 0 -> 2331 bytes doc/source/modules/gui/plot/img/Plot1D.png | Bin 0 -> 26947 bytes doc/source/modules/gui/plot/img/Plot2D.png | Bin 0 -> 59679 bytes doc/source/modules/gui/plot/img/PlotWidget.png | Bin 0 -> 32084 bytes doc/source/modules/gui/plot/img/PlotWindow.png | Bin 0 -> 47112 bytes doc/source/modules/gui/plot/img/PositionInfo.png | Bin 0 -> 3401 bytes doc/source/modules/gui/plot/img/StackView.png | Bin 0 -> 126723 bytes .../modules/gui/plot/img/StackViewMainWindow.png | Bin 0 -> 126821 bytes doc/source/modules/gui/plot/img/colorScale.png | Bin 0 -> 1653 bytes doc/source/modules/gui/plot/img/colorScaleBar.png | Bin 0 -> 4667 bytes doc/source/modules/gui/plot/img/fftAction0.png | Bin 0 -> 91165 bytes doc/source/modules/gui/plot/img/fftAction1.png | Bin 0 -> 38847 bytes doc/source/modules/gui/plot/img/linearColorbar.png | Bin 0 -> 6585 bytes doc/source/modules/gui/plot/img/logColorbar.png | Bin 0 -> 8575 bytes doc/source/modules/gui/plot/img/netCounts.png | Bin 0 -> 18711 bytes .../modules/gui/plot/img/plot_and_backend.png | Bin 0 -> 39491 bytes doc/source/modules/gui/plot/img/rawCounts.png | Bin 0 -> 18437 bytes doc/source/modules/gui/plot/img/roiwidget.png | Bin 0 -> 38771 bytes doc/source/modules/gui/plot/img/shiftAction0.png | Bin 0 -> 29092 bytes doc/source/modules/gui/plot/img/shiftAction3.png | Bin 0 -> 25949 bytes doc/source/modules/gui/plot/img/tickbar.png | Bin 0 -> 2080 bytes doc/source/modules/gui/plot/index.rst | 130 +++++ doc/source/modules/gui/plot/items.rst | 63 ++ doc/source/modules/gui/plot/plot.rst | 16 + doc/source/modules/gui/plot/plotactions.rst | 20 + .../modules/gui/plot/plotactions_examples.rst | 93 +++ doc/source/modules/gui/plot/plottools.rst | 36 ++ doc/source/modules/gui/plot/plotwidget.rst | 173 ++++++ doc/source/modules/gui/plot/plotwindow.rst | 30 + doc/source/modules/gui/plot/profile.rst | 20 + doc/source/modules/gui/plot/roi.rst | 17 + doc/source/modules/gui/plot/stackview.rst | 24 + doc/source/modules/gui/plot3d/actions.rst | 10 + doc/source/modules/gui/plot3d/dev.rst | 38 ++ doc/source/modules/gui/plot3d/glutils.rst | 67 +++ doc/source/modules/gui/plot3d/img/Plot3DWidget.png | Bin 0 -> 11811 bytes doc/source/modules/gui/plot3d/img/Plot3DWindow.png | Bin 0 -> 20571 bytes .../modules/gui/plot3d/img/SFViewParamTree.png | Bin 0 -> 19705 bytes .../modules/gui/plot3d/img/ScalarFieldView.png | Bin 0 -> 42407 bytes doc/source/modules/gui/plot3d/index.rst | 83 +++ doc/source/modules/gui/plot3d/plot3dwidget.rst | 15 + doc/source/modules/gui/plot3d/plot3dwindow.rst | 15 + doc/source/modules/gui/plot3d/scalarfieldview.rst | 50 ++ doc/source/modules/gui/plot3d/scene.rst | 84 +++ doc/source/modules/gui/plot3d/sfviewparamtree.rst | 13 + doc/source/modules/gui/plot3d/toolbars.rst | 29 + doc/source/modules/gui/plot3d/utils.rst | 12 + .../modules/gui/plot3d/viewer3dvolume_example.rst | 7 + doc/source/modules/gui/qt.rst | 8 + doc/source/modules/gui/update_icons_rst.py | 90 +++ doc/source/modules/gui/widgets/framebrowser.rst | 19 + doc/source/modules/gui/widgets/index.rst | 19 + doc/source/modules/gui/widgets/periodictable.rst | 37 ++ doc/source/modules/gui/widgets/tablewidget.rst | 42 ++ .../modules/gui/widgets/threadpoolpushbutton.rst | 14 + .../modules/gui/widgets/waitingpushbutton.rst | 13 + doc/source/modules/image/bilinear.rst | 9 + doc/source/modules/image/index.rst | 13 + doc/source/modules/image/medianfilter.rst | 7 + doc/source/modules/image/shapes.rst | 8 + doc/source/modules/image/sift.rst | 8 + doc/source/modules/index.rst | 14 + doc/source/modules/io/configdict.rst | 8 + doc/source/modules/io/dictdump.rst | 8 + doc/source/modules/io/index.rst | 25 + doc/source/modules/io/nxdata.rst | 8 + doc/source/modules/io/octaveh5.rst | 10 + doc/source/modules/io/specfile.rst | 83 +++ doc/source/modules/io/specfilewrapper.rst | 12 + doc/source/modules/io/spech5.rst | 11 + doc/source/modules/io/spectoh5.rst | 8 + doc/source/modules/io/utils.rst | 8 + doc/source/modules/math/combo.rst | 8 + doc/source/modules/math/fit/bgtheories.rst | 10 + doc/source/modules/math/fit/filters.rst | 18 + doc/source/modules/math/fit/fitmanager.rst | 18 + doc/source/modules/math/fit/fittheories.rst | 8 + doc/source/modules/math/fit/fittheory.rst | 8 + doc/source/modules/math/fit/functions.rst | 26 + doc/source/modules/math/fit/index.rst | 25 + doc/source/modules/math/fit/leastsq.rst | 16 + doc/source/modules/math/fit/peaksearch.rst | 10 + doc/source/modules/math/histogram.rst | 21 + doc/source/modules/math/index.rst | 13 + doc/source/modules/math/medianfilter.rst | 11 + doc/source/modules/resources.rst | 7 + doc/source/modules/test/index.rst | 20 + doc/source/modules/utils/array_like.rst | 7 + doc/source/modules/utils/decorators.rst | 7 + doc/source/modules/utils/html.rst | 7 + doc/source/modules/utils/index.rst | 11 + doc/source/modules/utils/weakref.rst | 7 + doc/source/overview.rst | 33 ++ doc/source/tutorials.rst | 17 + doc/source/virtualenv.rst | 203 +++++++ 164 files changed, 6348 insertions(+) create mode 100644 doc/source/Tutorials/Sift/sift.rst create mode 100644 doc/source/Tutorials/array_widget.rst create mode 100644 doc/source/Tutorials/fit.rst create mode 100644 doc/source/Tutorials/fitconfig.rst create mode 100644 doc/source/Tutorials/img/arraywidget3D_0.png create mode 100644 doc/source/Tutorials/img/arraywidget3D_1.png create mode 100644 doc/source/Tutorials/img/arraywidget5D_0.png create mode 100644 doc/source/Tutorials/img/arraywidget5D_1.png create mode 100644 doc/source/Tutorials/img/custom_config_scale0.5.png create mode 100644 doc/source/Tutorials/img/custom_config_scale1.0.png create mode 100644 doc/source/Tutorials/img/custom_config_scale2.1.png create mode 100644 doc/source/Tutorials/img/fitwidget1.png create mode 100644 doc/source/Tutorials/img/fitwidget2.png create mode 100644 doc/source/Tutorials/img/fitwidget3.png create mode 100644 doc/source/Tutorials/img/fitwidget4.png create mode 100644 doc/source/Tutorials/img/fitwidget5.png create mode 100644 doc/source/Tutorials/img/stripbg_plot1.png create mode 100644 doc/source/Tutorials/img/stripbg_plot2.png create mode 100644 doc/source/Tutorials/specfile_to_hdf5.rst create mode 100644 doc/source/changelog.rst create mode 100644 doc/source/conf.py create mode 100644 doc/source/description/img/sift_bench_cpu0.png create mode 100644 doc/source/description/img/sift_bench_cpu_kp.png create mode 100644 doc/source/description/img/sift_bench_cpu_res.png create mode 100644 doc/source/description/img/sift_bench_gpu0.png create mode 100644 doc/source/description/img/sift_bench_gpu_kp.png create mode 100644 doc/source/description/img/sift_bench_gpu_res.png create mode 100644 doc/source/description/img/sift_dog1.png create mode 100644 doc/source/description/img/sift_match1.png create mode 100644 doc/source/description/img/sift_orientation.png create mode 100644 doc/source/description/index.rst create mode 100644 doc/source/description/sift.rst create mode 100644 doc/source/img/silx.ico create mode 100644 doc/source/img/silx_large.png create mode 100755 doc/source/img/silx_small.png create mode 100644 doc/source/index.rst create mode 100644 doc/source/install.rst create mode 100644 doc/source/license.rst create mode 100644 doc/source/modules/gui/console.rst create mode 100644 doc/source/modules/gui/data/arraytable.rst create mode 100644 doc/source/modules/gui/data/dataviewer.rst create mode 100644 doc/source/modules/gui/data/dataviewerframe.rst create mode 100644 doc/source/modules/gui/data/img/DataViewer.png create mode 100644 doc/source/modules/gui/data/img/DataViewerFrame.png create mode 100644 doc/source/modules/gui/data/img/NumpyAxesSelector.png create mode 100644 doc/source/modules/gui/data/index.rst create mode 100644 doc/source/modules/gui/data/numpyaxesselector.rst create mode 100644 doc/source/modules/gui/data/textformatter.rst create mode 100644 doc/source/modules/gui/designer.rst create mode 100644 doc/source/modules/gui/fit/backgroundwidget.rst create mode 100644 doc/source/modules/gui/fit/fitwidget.rst create mode 100644 doc/source/modules/gui/fit/img/bgwidget.png create mode 100644 doc/source/modules/gui/fit/index.rst create mode 100644 doc/source/modules/gui/hdf5/examples_hdf5widget.rst create mode 100644 doc/source/modules/gui/hdf5/getting_started.rst create mode 100644 doc/source/modules/gui/hdf5/h5node.rst create mode 100644 doc/source/modules/gui/hdf5/hdf5contextmenuevent.rst create mode 100644 doc/source/modules/gui/hdf5/hdf5treemodel.rst create mode 100644 doc/source/modules/gui/hdf5/hdf5treeview.rst create mode 100644 doc/source/modules/gui/hdf5/img/Hdf5Example.png create mode 100644 doc/source/modules/gui/hdf5/img/Hdf5TreeView.png create mode 100644 doc/source/modules/gui/hdf5/index.rst create mode 100644 doc/source/modules/gui/hdf5/nexussortfilterproxymodel.rst create mode 100644 doc/source/modules/gui/icons.rst create mode 100644 doc/source/modules/gui/index.rst create mode 100644 doc/source/modules/gui/plot/dev.rst create mode 100644 doc/source/modules/gui/plot/getting_started.rst create mode 100644 doc/source/modules/gui/plot/imageview.rst create mode 100644 doc/source/modules/gui/plot/img/ImageView.png create mode 100644 doc/source/modules/gui/plot/img/LimitsToolBar.png create mode 100644 doc/source/modules/gui/plot/img/Plot1D.png create mode 100644 doc/source/modules/gui/plot/img/Plot2D.png create mode 100644 doc/source/modules/gui/plot/img/PlotWidget.png create mode 100644 doc/source/modules/gui/plot/img/PlotWindow.png create mode 100644 doc/source/modules/gui/plot/img/PositionInfo.png create mode 100644 doc/source/modules/gui/plot/img/StackView.png create mode 100644 doc/source/modules/gui/plot/img/StackViewMainWindow.png create mode 100644 doc/source/modules/gui/plot/img/colorScale.png create mode 100644 doc/source/modules/gui/plot/img/colorScaleBar.png create mode 100644 doc/source/modules/gui/plot/img/fftAction0.png create mode 100644 doc/source/modules/gui/plot/img/fftAction1.png create mode 100644 doc/source/modules/gui/plot/img/linearColorbar.png create mode 100644 doc/source/modules/gui/plot/img/logColorbar.png create mode 100644 doc/source/modules/gui/plot/img/netCounts.png create mode 100644 doc/source/modules/gui/plot/img/plot_and_backend.png create mode 100644 doc/source/modules/gui/plot/img/rawCounts.png create mode 100644 doc/source/modules/gui/plot/img/roiwidget.png create mode 100644 doc/source/modules/gui/plot/img/shiftAction0.png create mode 100644 doc/source/modules/gui/plot/img/shiftAction3.png create mode 100644 doc/source/modules/gui/plot/img/tickbar.png create mode 100644 doc/source/modules/gui/plot/index.rst create mode 100644 doc/source/modules/gui/plot/items.rst create mode 100644 doc/source/modules/gui/plot/plot.rst create mode 100644 doc/source/modules/gui/plot/plotactions.rst create mode 100644 doc/source/modules/gui/plot/plotactions_examples.rst create mode 100644 doc/source/modules/gui/plot/plottools.rst create mode 100644 doc/source/modules/gui/plot/plotwidget.rst create mode 100644 doc/source/modules/gui/plot/plotwindow.rst create mode 100644 doc/source/modules/gui/plot/profile.rst create mode 100644 doc/source/modules/gui/plot/roi.rst create mode 100644 doc/source/modules/gui/plot/stackview.rst create mode 100644 doc/source/modules/gui/plot3d/actions.rst create mode 100644 doc/source/modules/gui/plot3d/dev.rst create mode 100644 doc/source/modules/gui/plot3d/glutils.rst create mode 100644 doc/source/modules/gui/plot3d/img/Plot3DWidget.png create mode 100644 doc/source/modules/gui/plot3d/img/Plot3DWindow.png create mode 100644 doc/source/modules/gui/plot3d/img/SFViewParamTree.png create mode 100644 doc/source/modules/gui/plot3d/img/ScalarFieldView.png create mode 100644 doc/source/modules/gui/plot3d/index.rst create mode 100644 doc/source/modules/gui/plot3d/plot3dwidget.rst create mode 100644 doc/source/modules/gui/plot3d/plot3dwindow.rst create mode 100644 doc/source/modules/gui/plot3d/scalarfieldview.rst create mode 100644 doc/source/modules/gui/plot3d/scene.rst create mode 100644 doc/source/modules/gui/plot3d/sfviewparamtree.rst create mode 100644 doc/source/modules/gui/plot3d/toolbars.rst create mode 100644 doc/source/modules/gui/plot3d/utils.rst create mode 100644 doc/source/modules/gui/plot3d/viewer3dvolume_example.rst create mode 100644 doc/source/modules/gui/qt.rst create mode 100644 doc/source/modules/gui/update_icons_rst.py create mode 100644 doc/source/modules/gui/widgets/framebrowser.rst create mode 100644 doc/source/modules/gui/widgets/index.rst create mode 100644 doc/source/modules/gui/widgets/periodictable.rst create mode 100644 doc/source/modules/gui/widgets/tablewidget.rst create mode 100644 doc/source/modules/gui/widgets/threadpoolpushbutton.rst create mode 100644 doc/source/modules/gui/widgets/waitingpushbutton.rst create mode 100644 doc/source/modules/image/bilinear.rst create mode 100644 doc/source/modules/image/index.rst create mode 100644 doc/source/modules/image/medianfilter.rst create mode 100644 doc/source/modules/image/shapes.rst create mode 100644 doc/source/modules/image/sift.rst create mode 100644 doc/source/modules/index.rst create mode 100644 doc/source/modules/io/configdict.rst create mode 100644 doc/source/modules/io/dictdump.rst create mode 100644 doc/source/modules/io/index.rst create mode 100644 doc/source/modules/io/nxdata.rst create mode 100644 doc/source/modules/io/octaveh5.rst create mode 100644 doc/source/modules/io/specfile.rst create mode 100644 doc/source/modules/io/specfilewrapper.rst create mode 100644 doc/source/modules/io/spech5.rst create mode 100644 doc/source/modules/io/spectoh5.rst create mode 100644 doc/source/modules/io/utils.rst create mode 100644 doc/source/modules/math/combo.rst create mode 100644 doc/source/modules/math/fit/bgtheories.rst create mode 100644 doc/source/modules/math/fit/filters.rst create mode 100644 doc/source/modules/math/fit/fitmanager.rst create mode 100644 doc/source/modules/math/fit/fittheories.rst create mode 100644 doc/source/modules/math/fit/fittheory.rst create mode 100644 doc/source/modules/math/fit/functions.rst create mode 100644 doc/source/modules/math/fit/index.rst create mode 100644 doc/source/modules/math/fit/leastsq.rst create mode 100644 doc/source/modules/math/fit/peaksearch.rst create mode 100644 doc/source/modules/math/histogram.rst create mode 100644 doc/source/modules/math/index.rst create mode 100644 doc/source/modules/math/medianfilter.rst create mode 100644 doc/source/modules/resources.rst create mode 100644 doc/source/modules/test/index.rst create mode 100644 doc/source/modules/utils/array_like.rst create mode 100644 doc/source/modules/utils/decorators.rst create mode 100644 doc/source/modules/utils/html.rst create mode 100644 doc/source/modules/utils/index.rst create mode 100644 doc/source/modules/utils/weakref.rst create mode 100644 doc/source/overview.rst create mode 100644 doc/source/tutorials.rst create mode 100644 doc/source/virtualenv.rst (limited to 'doc/source') diff --git a/doc/source/Tutorials/Sift/sift.rst b/doc/source/Tutorials/Sift/sift.rst new file mode 100644 index 0000000..7168cf3 --- /dev/null +++ b/doc/source/Tutorials/Sift/sift.rst @@ -0,0 +1,315 @@ + +SIFT image alignment tutorial +============================= + +SIFT (Scale-Invariant Feature Transform) is an algorithm developped by +David Lowe in 1999. It is a worldwide reference for image alignment and +object recognition. The robustness of this method enables to detect +features at different scales, angles and illumination of a scene. + +Silx provides an implementation of SIFT in OpenCL, meaning that it can +run on Graphics Processing Units and Central Processing Units as well. +Interest points are detected in the image, then data structures called +*descriptors* are built to be characteristic of the scene, so that two +different images of the same scene have similar descriptors. They are +robust to transformations like translation, rotation, rescaling and +illumination change, which make SIFT interesting for image stitching. + +In the fist stage, descriptors are computed from the input images. Then, +they are compared to determine the geometric transformation to apply in +order to align the images. This implementation can run on most graphic +cards and CPU, making it usable on many setups. OpenCL processes are +handled from Python with PyOpenCL, a module to access OpenCL parallel +computation API. + +This tutuorial explains the three subsequent steps: + +- keypoint extraction +- Keypoint matching +- image alignment + +All the tutorial has been made using the Jupyter notebook. + +.. code:: python + + import time + start_time = time.time() + %pylab nbagg + + +.. parsed-literal:: + + Populating the interactive namespace from numpy and matplotlib + + +.. code:: python + + # display test image + import silx + print("Silx version %s"%silx.version) + + from PIL import Image + from silx.test.utils import utilstest + path = utilstest.getfile("lena.png") + image = numpy.asarray(Image.open(path)) + fig, ax = subplots() + ax.imshow(image, cmap="gray") + + +.. parsed-literal:: + + Silx version 0.5.0-dev0 + + + +.. parsed-literal:: + + + + + +.. raw:: html + + + + + + +.. parsed-literal:: + + + + + +.. code:: python + + #Initialization of the sift object is time consuming: it compiles all the code. + import os + #set to 1 to see the compilation going on + os.environ["PYOPENCL_COMPILER_OUTPUT"] = "0" + from silx.image import sift + #switch to "GPU" to "CPU" to enable fail-save version. + %time sift_ocl = sift.SiftPlan(template=image, devicetype="GPU") + + +.. parsed-literal:: + + CPU times: user 112 ms, sys: 112 ms, total: 224 ms + Wall time: 240 ms + + +.. code:: python + + print("Time for calculating the keypoints on one image of size %sx%s"%image.shape[:2]) + %time keypoints = sift_ocl(image) + print("Number of keypoints: %s"%len(keypoints)) + print("Keypoint content:") + print(keypoints.dtype) + print("x: %.3f \t y: %.3f \t sigma: %.3f \t angle: %.3f" % + (keypoints[-1].x,keypoints[-1].y,keypoints[-1].scale,keypoints[-1].angle)) + print("descriptor:") + print(keypoints[-1].desc) + + +.. parsed-literal:: + + Time for calculating the keypoints on one image of size 512x512 + CPU times: user 652 ms, sys: 0 ns, total: 652 ms + Wall time: 649 ms + Number of keypoints: 411 + Keypoint content: + (numpy.record, [('x', ' + + + +.. raw:: html + + + + + + +.. parsed-literal:: + + [] + + + +.. code:: python + + #Diplaying keypoints by scale: + fig, ax = subplots() + ax.hist(keypoints[:].scale, 100) + ax.set_xlabel("scale") + + + +.. parsed-literal:: + + + + + +.. raw:: html + + + + + + +.. parsed-literal:: + + + + + +.. code:: python + + #One can see 3 groups of keypoints, boundaries at: 8 and 20. Let's display them using colors. + S = 8 + L = 20 + tiny = keypoints[keypoints[:].scale=S)] + bigger = keypoints[keypoints[:].scale>=L] + + fig, ax = subplots() + ax.imshow(image, cmap="gray") + ax.plot(tiny[:].x, tiny[:].y,",g", label="tiny") + ax.plot(small[:].x, small[:].y,".b", label="small") + ax.plot(bigger[:].x, bigger[:].y,"or", label="large") + ax.legend() + + + +.. parsed-literal:: + + + + + +.. raw:: html + + + + + + +.. parsed-literal:: + + + + + +Image matching and alignment +---------------------------- + +Matching can also be performed on the device (GPU) as every single +keypoint from an image needs to be compared with all keypoints from the +second image. + +In this simple example we will simple offset the first image by a few +pixels + +.. code:: python + + shifted = numpy.zeros_like(image) + shifted[5:,8:] = image[:-5, :-8] + shifted_points = sift_ocl(shifted) + +.. code:: python + + %time mp = sift.MatchPlan() + %time match = mp(keypoints, shifted_points) + print("Number of Keypoints with for image 1 : %i, For image 2 : %i, Matching keypoints: %i" % (keypoints.size, shifted_points.size, match.shape[0])) + from numpy import median + print("Measured offsets dx: %.3f, dy: %.3f"%(median(match[:,1].x-match[:,0].x),median(match[:,1].y-match[:,0].y))) + + +.. parsed-literal:: + + CPU times: user 20 ms, sys: 128 ms, total: 148 ms + Wall time: 167 ms + CPU times: user 8 ms, sys: 4 ms, total: 12 ms + Wall time: 14.9 ms + Number of Keypoints with for image 1 : 411, For image 2 : 399, Matching keypoints: 351 + Measured offsets dx: 8.000, dy: 5.000 + + +.. code:: python + + # Example of usage of the automatic alignment: + import scipy.ndimage + rotated = scipy.ndimage.rotate(image, 20, reshape=False) + sa = sift.LinearAlign(image) + fig,ax = subplots(1, 3, figsize=(12,4)) + ax[0].imshow(image) + ax[1].imshow(rotated) + ax[2].imshow(sa.align(rotated)) + + +.. parsed-literal:: + + /scisoft/users/jupyter/jupy34/lib/python3.4/site-packages/pyopencl/cffi_cl.py:1469: CompilerWarning: Non-empty compiler output encountered. Set the environment variable PYOPENCL_COMPILER_OUTPUT=1 to see more. + "to see more.", CompilerWarning) + + + +.. parsed-literal:: + + + + + +.. raw:: html + + + + + + +.. parsed-literal:: + + + + + +References +~~~~~~~~~~ + +- David G. Lowe, Distinctive image features from scale-invariant + keypoints, International Journal of Computer Vision, vol. 60, no 2, + 2004, p. 91–110 - "http://www.cs.ubc.ca/~lowe/papers/ijcv04.pdf" + +.. code:: python + + print("Total execution time: %.3fs" % (time.time() - start_time)) + + +.. parsed-literal:: + + Total execution time: 6.190s + diff --git a/doc/source/Tutorials/array_widget.rst b/doc/source/Tutorials/array_widget.rst new file mode 100644 index 0000000..f2ccfdf --- /dev/null +++ b/doc/source/Tutorials/array_widget.rst @@ -0,0 +1,246 @@ + +.. currentmodule:: silx.gui.data.ArrayTableWidget + +ArrayTableWidget +================ + +:class:`ArrayTableWidget` is a widget designed to visualize numpy arrays or h5py datasets. + +3D example +---------- + +Let's look at a simple usage example: + +.. code-block:: python + + from silx.gui import qt + from silx.gui.data.ArrayTableWidget import ArrayTableWidget + import numpy + array = numpy.arange(1000) + array.shape = (5, 10, 20) + app = qt.QApplication([]) + w = ArrayTableWidget() + w.setArrayData(array, labels=True) + w.show() + app.exec_() + + +.. |imgArray0| image:: img/arraywidget3D_0.png + :height: 300px + :align: middle + +|imgArray0| + +We get a widget that allows us to see a *slice*, or a *frame*, of 2D data +with 10 lines and 20 columns, in a 3D array (5 x 10 x 20). +The column index corresponds to the last dimension of the array, and the +row index corresponds to the second to last dimension. The first index can be browsed +using a slider, icons or a text entry for access to any given slice among the 5 available. + +The parameter ``labels=True`` of :meth:`setArrayData` causes the browser to be labeled +*Dimension 0*. + +If we want to see slices in different perspective, we can use +:meth:`ArrayTableWidget.setPerspective`. The perspective is defined as the list +of dimensions that are not represented in the frame, orthogonal to it. +For a 3D array, there are 3 possible perspectives: *[0, ]* (the default perspective), +*[1, ]* and *[2, ]*. + +Lets change the perspective: + +.. code-block:: python + + w.setPerspective([1]) + +.. |imgArray1| image:: img/arraywidget3D_1.png + :height: 300px + :align: middle + +|imgArray1| + +What we see now is a frame of *5 x 20* values, and the browser now browses the second dimension +to select one of 10 available frames. The label is updated accordingly to show *Dimension 1*. + +To select a different frame programmatically, without using the browser, you can +use the :meth:`ArrayTableWidget.setIndex` method. To select the 9-th frame, use: + +.. code-block:: python + + w.setIndex([8]) + +More dimensions +--------------- + +This widget can be used for arrays with any numbers of dimensions. Let's create +a 5-dimensional array and display it: + +.. code-block:: python + + array = numpy.arange(10000) + array.shape = (5, 2, 10, 5, 20) + w.setArrayData(array, labels=True) + +.. |imgArray2| image:: img/arraywidget5D_0.png + :height: 300px + :align: middle + +|imgArray2| + +We now have 3 frames browsers, one for each one of the orthogonal dimensions. + +Let's look at a frame whose axes are along the second +and the fourth dimension, by setting the orthogonal axes to the first, +third and fifth dimensions: + +.. code-block:: python + + w.setPerspective([0, 2, 4]) + +.. |imgArray3| image:: img/arraywidget5D_1.png + :height: 300px + :align: middle + +|imgArray3| + + +Listing all the orthogonal dimensions might not feel very convenient for arrays +with more than 3 or 4 dimensions. +Fortunately, you can use the opposite approach of defining the two axes +parallel to the frame, using :meth:`ArrayTableWidget.setFrameAxes`: + +.. code-block:: python + + w.setFrameAxes(row_axis=1, col_axis=3) + +This achieves the exact same result as ``w.setPerspective([0, 2, 4])``. + +.. note:: + + Currently you cannot switch the row and column axes. The row axis + is always the lowest free dimension and the column axis is the + highest one with the current implementation. + So setting ``w.setFrameAxes(row_axis=3, col_axis=1)`` would not modify + the table axes. + + For the same reason, the order of the dimensions given as parameter to + :meth:`setPerspective` is not significant. + +To select a frame programmaticaly, you can again use :meth:`setFrameIndex`. +This time you must provide 3 unique indices: + +.. code-block:: python + + w.setIndex([2, 5, 14]) + +The 3 indices relate to the first, third and fifth dimensions. + +The frame index must always be defined as indices on the orthogonal axes/dimensions, +as defined by the *perspective*. + +Editing the data +---------------- + +By default, the data displayed in the table view can be edited. If you modify +a cell with a valid value, it will be modified in the internal data model. + +You can get the modified data with the following line: + +.. code-block:: python + + newdata = w.getData() + +This will give you a copy of the data, by default. + +If you want the data to be read-only, not editable, you must specify it when +you set the data: + +.. code-block:: python + + w.setDataArray(array, editable=False) + +More performances +----------------- + +By default, the method :meth:`setArrayData` creates a copy of the data array +for internal storage. This ensures that the original data object is not +modified when a cell of the table is changed interactively in the widget. + +This behavior has a negative impact on performances, especially for large data arrays. +To avoid this, you can explicitely disable the copy operation when setting the data: + +.. code-block:: python + + w.setArrayData(array, copy=False) + +The internal data array used by the widget is then a reference +to the same data object as the original *array*. The memory is shared and +is not duplicated. + +.. warning:: + + This can cause side-effects, if your original array is re-used elsewhere + in your program. + +Similarly, you can pass *copy=False* to the :meth:`getData` method, to avoid +doing a data copy operation: + +.. code-block:: python + + newdata = w.getData(copy=False) + +The variable *newdata* is then a reference to the internal widget data. + +.. warning:: + + Modifying the internal data used by the widget can have unpredictable + consequences. + +Background color +---------------- + +You can set the background color for each cell by passing a numpy array of +RGB colors to the :meth:`setArrayColors` method. + +The colors array must have one more dimension than the data array. This dimension +must be of length 3 for RGB colors or length 4 for RGBA colors. + +The colors array associates 3 (or 4) integers between 0 and 255 to each value +in the data array. The values represent the red, green, blue and alpha (opacity) +channels. + +In the following examples, we create a table displaying a complete palette +of RGB colors. + +.. code-block:: python + + import numpy + from silx.gui import qt + from silx.gui.widgets.ArrayTableWidget import ArrayTableWidget + + # data array + data = numpy.arange(256**3) + data.shape = 256, 256, 256 + + # RGB colors array + bcolors = numpy.empty((256, 256, 256, 3), dtype=numpy.uint8) + # fill red channel + bcolors[..., 0] = data[:] & 255 + # green + bcolors[..., 1] = (data[:] & (255 << 8)) >> 8 + # blue + bcolors[..., 2] = (data[:] & (255 << 16)) >> 16 + + # make text contrast with background (XOR) + fcolors = numpy.bitwise_xor(bcolors, 255) + + app = qt.QApplication([]) + + atw = ArrayTableWidget() + atw.setArrayData(data, copy=False) + atw.setArrayColors(bgcolors=bcolors, + fgcolors=fcolors) + atw.show() + + app.exec_() + + diff --git a/doc/source/Tutorials/fit.rst b/doc/source/Tutorials/fit.rst new file mode 100644 index 0000000..1305299 --- /dev/null +++ b/doc/source/Tutorials/fit.rst @@ -0,0 +1,635 @@ + +.. _fit-tutorial: + +Fit tools +--------- + +.. contents:: :local: + +.. _leastsq-tutorial: + +Using :func:`leastsq` ++++++++++++++++++++++ + +.. currentmodule:: silx.math.fit + +Running an iterative fit with :func:`leastsq` involves the following steps: + + - designing a fit model function that has the signature ``f(x, ...)``, + where ``x`` is an array of values of the independant variable and all + remaining parameters are the parameters to be fitted + - defining the sequence of initial values for all parameters to be fitted. + You can usually start with ``[1., 1., ...]`` if you don't know a better + estimate. The algorithm is robust enough to converge to a solution most + of the time. + - setting constraints (optional) + +Data required to perform a fit is: + + - an array of ``x`` values (abscissa, independant variable) + - an array of ``y`` data points + - the ``sigma`` array of uncertainties associated to each data point. + This is optional, by default each data point gets assigned a weight of 1. + +Standard fit +************ + +Let's demonstrate this process in a short example, using synthetic data. +We generate an array of synthetic data using a polynomial function of degree 4, +and try to use :func:`leastsq` to find back the functions parameters. + +.. code-block:: python + + import numpy + from silx.math.fit import leastsq + + # create some synthetic polynomial data + x = numpy.arange(1000) + y = 2.4 * x**4 - 10. * x**3 + 15.2 * x**2 - 24.6 * x + 150. + + # define our fit function: a generic polynomial of degree 4 + def poly4(x, a, b, c, d, e): + return a * x**4 + b * x**3 + c * x**2 + d * x + e + + # The fit is an iterative process that requires an initial + # estimation of the parameters. Let's just use 1s. + initial_parameters = numpy.array([1., 1., 1., 1., 1.]) + + # Run fit + fitresult = leastsq(model=poly4, + xdata=x, + ydata=y, + p0=initial_parameters, + full_output=True) + + # leastsq with full_output=True returns 3 objets + optimal_parameters, covariance, infodict = fitresult + # the first object is an array with the fitted parameters + a, b, c, d, e = optimal_parameters + + print("Fit took %d iterations" % infodict["niter"]) + print("Reduced chi-square: %f" % infodict["reduced_chisq"]) + print("Theoretical parameters:\n\t" + + "a=2.4, b=-10, c=15.2, d=-24.6, e=150") + print("Optimal parameters for y2 fitting:\n\t" + + "a=%f, b=%f, c=%f, d=%f, e=%f" % (a, b, c, d, e)) + +The output of this program is:: + + Fit took 35 iterations + Reduced chi-square: 682592.670690 + Theoretical parameters: + a=2.4, b=-10, c=15.2, d=-24.6, e=150 + Optimal parameters for y fitting: + a=2.400000, b=-9.999665, c=14.970422, d=31.683448, e=-3216.131136 + +We can see that this fit result is poor. In particular, parameters ``d`` and ``e`` +are very poorly fitted. +This is most likely due to numerical rounding errors. As we are dealing with +very large values in our ``y`` array, we are affected by the limits of how +floating point numbers are represented by computers. The larger a value, the +larger its rounding error. + +If you limit the ``x`` range to deal with +smaller ``y`` values, the fit result becomes perfect. In our example, replacing ``x`` +with:: + + x = numpy.arange(100) + +produces the following result:: + + Fit took 9 iterations + Reduced chi-square: 0.000000 + Theoretical parameters: + a=2.4, b=-10, c=15.2, d=-24.6, e=150 + Optimal parameters for y fitting: + a=2.400000, b=-10.000000, c=15.200000, d=-24.600000, e=150.000000 + + + +Constrained fit +*************** + +But let's revert back to our initial ``x = numpy.arange(1000)``, to experiment +with different approaches to improving the fit. + +The :func:`leastsq` functions provides +a way to set constraints on parameters. You can for instance assert that a given +parameter must remain equal to it's initial value, or define an acceptable range +for it to vary, or decide that a parameter must be equal to another parameter +multiplied by a certain factor. This is very useful in cases in which you have +enough knowledge to make reasonable assumptions on some parameters. + +In our case, we will set constraints on ``d`` and ``e``. We will quote ``d`` to +stay in the range between -25 and -24, and fix ``e`` to 150. + +Replace the call to :func:`leastsq` by following lines: + +.. code-block:: python + + # Define constraints + cons = [[0, 0, 0], # a: no constraint + [0, 0, 0], # b: no constraint + [0, 0, 0], # c: no constraint + [2, -25., -23.], # -25 < d < -24 + [3, 0, 0]] # e is fixed to initial value + fitresult = leastsq(poly4, x, y, + # initial values must be consistent with constraints + p0=[1., 1., 1., -24., 150.], + constraints=cons, + full_output=True) + +The output of this program is:: + + Constrained fit took 100 iterations + Reduced chi-square: 3.749280 + Theoretical parameters: + a=2.4, b=-10, c=15.2, d=-24.6, e=150 + Optimal parameters for y fitting: + a=2.400000, b=-9.999999, c=15.199648, d=-24.533014, e=150.000000 + +The chi-square value is much improved and the results are much better, at the +cost of more iterations. + +Weighted fit +************ +A third approach to improve our fit is to define uncertainties for the data. +The larger the uncertainty on a data sample, the smaller its weight will be +in the least-square problem. + +In our case, we do not know the uncertainties associated to our data. We could +determine the uncertainties due to numerical rounding errors, but let's just use +a common approach that requires less work: use the square-root of the data values +as their uncertainty value: + +.. code-block:: python + + sigma = numpy.sqrt(y) + + # Fit y + fitresult = leastsq(model=poly4, + xdata=x, + ydata=y, + sigma=sigma, + p0=initial_parameters, + full_output=True) + +This results in a great improvement:: + + Weighted fit took 6 iterations + Reduced chi-square: 0.000000 + Theoretical parameters: + a=2.4, b=-10, c=15.2, d=-24.6, e=150 + Optimal parameters for y fitting: + a=2.400000, b=-10.000000, c=15.200000, d=-24.600000, e=150.000000 + +The resulting fit is perfect. The very large ``y`` values with their very large +associated uncertainties have been practicaly rejected from the fit process. The fit +converged even faster than with the solution of limiting the ``x`` range to +0 -- 100. + +.. _fitmanager-tutorial: + +Using :class:`FitManager` ++++++++++++++++++++++++++ + +.. currentmodule:: silx.math.fit.fitmanager + +A :class:`FitManager` is a tool that provides a way of handling fit functions, +associating estimation functions to estimate the initial parameters, modify +the configuration parameters for the fit (enabling or disabling weights...) or +for the estimation function, and choosing a background model. + +It provides an abstraction layer on top of :func:`leastsq`. + +Weighted polynomial fit +*********************** + +The following program accomplishes the same weighted fit of a polynomial as in +the previous tutorial (`Weighted fit`_) + +.. code-block:: python + + import numpy + from silx.math.fit.fitmanager import FitManager + + # Create synthetic data with a sum of gaussian functions + x = numpy.arange(1000).astype(numpy.float) + y = 2.4 * x**4 - 10. * x**3 + 15.2 * x**2 - 24.6 * x + 150. + + # define our fit function: a generic polynomial of degree 4 + def poly4(x, a, b, c, d, e): + return a * x**4 + b * x**3 + c * x**2 + d * x + e + + # define an estimation function to that returns initial parameters + # and constraints + def esti(x, y): + p0 = numpy.array([1., 1., 1., 1., 1.]) + cons = numpy.zeros(shape=(5, 3)) + return p0, cons + + # Fitting + fit = FitManager() + fit.setdata(x=x, y=y) + + fit.addtheory("polynomial", + function=poly4, + # any list of 5 parameter names would be OK + parameters=["A", "B", "C", "D", "E"], + estimate=esti) + fit.settheory('polynomial') + fit.configure(WeightFlag=True) + fit.estimate() + fit.runfit() + + print("\n\nFit took %d iterations" % fit.niter) + print("Reduced chi-square: %f" % fit.chisq) + print("Theoretical parameters:\n\t" + + "a=2.4, b=-10, c=15.2, d=-24.6, e=150") + a, b, c, d, e = (param['fitresult'] for param in fit.fit_results) + print("Optimal parameters for y2 fitting:\n\t" + + "a=%f, b=%f, c=%f, d=%f, e=%f" % (a, b, c, d, e)) + + +The result is the same as in our weighted :func:`leastsq` example, +as expected:: + + Fit took 6 iterations + Reduced chi-square: 0.000000 + Theoretical parameters: + a=2.4, b=-10, c=15.2, d=-24.6, e=150 + Optimal parameters for y2 fitting: + a=2.400000, b=-10.000000, c=15.200000, d=-24.600000, e=150.000000 + +Fitting gaussians +***************** + +The :class:`FitManager` object is especially useful for fitting multi-peak +gaussian-shaped spectra. The *silx* module :mod:`silx.math.fit.fittheories` +provides fit functions and their associated estimation functions that are +specifically designed for this purpose. + +These fit functions can handle variable number of parameters defining a +variable number of peaks, and the estimation functions use a peak detection +algorithm to determine how many initial parameters must be returned. + +For the sake of the example, let's test the multi-peak fitting on synthetic +data, generated using another *silx* module: :mod:`silx.math.fit.functions`. + +.. code-block:: python + + import numpy + from silx.math.fit.functions import sum_gauss + from silx.math.fit import fittheories + from silx.math.fit.fitmanager import FitManager + + # Create synthetic data with a sum of gaussian functions + x = numpy.arange(1000).astype(numpy.float) + + # height, center x, fwhm + p = [1000, 100., 250, # 1st peak + 255, 690., 45, # 2nd peak + 1500, 800.5, 95] # 3rd peak + + y = sum_gauss(x, *p) + + # Fitting + fit = FitManager() + fit.setdata(x=x, y=y) + fit.loadtheories(fittheories) + fit.settheory('Gaussians') + fit.estimate() + fit.runfit() + + print("Searched parameters = %s" % p) + print("Obtained parameters : ") + dummy_list = [] + for param in fit.fit_results: + print(param['name'], ' = ', param['fitresult']) + dummy_list.append(param['fitresult']) + print("chisq = ", fit.chisq) + +And the result of this program is:: + + Searched parameters = [1000, 100.0, 250, 255, 690.0, 45, 1500, 800.5, 95] + Obtained parameters : + ('Height1', ' = ', 1000.0) + ('Position1', ' = ', 100.0) + ('FWHM1', ' = ', 250.0) + ('Height2', ' = ', 255.0) + ('Position2', ' = ', 690.0) + ('FWHM2', ' = ', 44.999999999999993) + ('Height3', ' = ', 1500.0) + ('Position3', ' = ', 800.5) + ('FWHM3', ' = ', 95.000000000000014) + ('chisq = ', 0.0) + +In addition to gaussians, we could have fitted several other similar type of +functions: asymetric gaussian functions, lorentzian functions, +Pseudo-Voigt functions or hypermet tailing functions. + +The :meth:`loadtheories` method can also be used to load user defined +functions. Instead of a module, a path to a Python source file can be given +as a parameter. This source file must adhere to certain conventions, as explained +in the documentation of :mod:`silx.math.fit.fittheories` and +:mod:`silx.math.fit.fittheory.FitTheory`. + +Subtracting a background +************************ + +:class:`FitManager` provides a few standard background theories, for cases when +a background signal is superimposed on the multi-peak spectrum. + +For example, let's add a linear background to our synthetic data, and see how +:class:`FitManager` handles the fitting. + +In our previous example, redefine ``y`` as follows: + +.. code-block:: python + + p = [1000, 100., 250, + 255, 690., 45, + 1500, 800.5, 95] + y = sum_gauss(x, *p) + # add a synthetic linear background + y += 0.13 * x + 100. + +Before the line ``fit.estimate()``, add the following line: + +.. code-block:: python + + fit.setbackground('Linear') + +The result becomes:: + + Searched parameters = [1000, 100.0, 250, 255, 690.0, 45, 1500, 800.5, 95] + Obtained parameters : + ('Constant', ' = ', 100.00000000000001) + ('Slope', ' = ', 0.12999999999999998) + ('Height1', ' = ', 1000.0) + ('Position1', ' = ', 100.0) + ('FWHM1', ' = ', 249.99999999999997) + ('Height2', ' = ', 255.00000000000003) + ('Position2', ' = ', 690.0) + ('FWHM2', ' = ', 44.999999999999993) + ('Height3', ' = ', 1500.0) + ('Position3', ' = ', 800.5) + ('FWHM3', ' = ', 95.0) + ('chisq = ', 3.1789004676997597e-27) + +The available background theories are: *Linear*, *Constant* and *Strip*. + +The strip background is a popular background model that can compute and +subtract any background shape as long as its curvature is significantly +lower than the peaks' curvature. In other words, as long as the background +signal is significantly smoother than the actual signal, it can be easily +computed. + +The main parameters required by the strip function are the strip width *w* +and the number of iterations. At each iteration, if the contents of channel *i*, +``y(i)``, is above the average of the contents of the channels at *w* channels of +distance, ``y(i-w)`` and ``y(i+w)``, ``y(i)`` is replaced by the average. +At the end of the process we are left with something that resembles a spectrum +in which the peaks have been "stripped". + +The following example illustrates the strip background removal process: + +.. code-block:: python + + from silx.sx import plot + from silx.gui import qt + import numpy + from silx.math.fit.filters import strip + from silx.math.fit.functions import sum_gauss + + x = numpy.arange(5000) + # (height1, center1, fwhm1, ...) 5 peaks + params1 = (50, 500, 100, + 20, 2000, 200, + 50, 2250, 100, + 40, 3000, 75, + 23, 4000, 150) + y0 = sum_gauss(x, *params1) + + # random values between [-1;1] + noise = 2 * numpy.random.random(5000) - 1 + # make it +- 5% + noise *= 0.05 + + # 2 gaussians with very large fwhm, as background signal + actual_bg = sum_gauss(x, 15, 3500, 3000, 5, 1000, 1500) + + # Add 5% random noise to gaussians and add background + y = y0 * (1 + noise) + actual_bg + + # compute strip background model + strip_bg = strip(y, w=5, niterations=5000) + + # plot results + app = qt.QApplication([]) + plot(x, y, x, actual_bg, x, strip_bg) + plot(x, y, x, (y - strip_bg)) + app.exec_() + +.. |imgStrip1| image:: img/stripbg_plot1.png + :height: 300px + :align: middle + +.. |imgStrip2| image:: img/stripbg_plot2.png + :height: 300px + :align: middle + +.. list-table:: + :widths: 1 2 + + * - |imgStrip1| + - Data with background in black (``y``), actual background in red, computed strip + background in green + * - |imgStrip2| + - Data with background in blue, data after subtracting strip background in black + +The strip also removes the statistical noise, so the computed strip background +will be slightly lower than the actual background. This can be solved by +performing a smoothing prior to the strip computation. + +See the `PyMca documentation `_ +for more information on the strip background. + +To configure the strip background model of :class:`FitManager`, use its :meth:`configure` +method to modify the following parameters: + + - *StripWidth*: strip width parameter *w*, mentionned earlier + - *StripNIterations*: number of iterations + - *StripThresholdFactor*: if this parameter is left to its default value 1, + the algorithm behaves as explained earlier: ``y(i)`` is compared to the average of + ``y(i-1)`` and ``y(i+1)``. + If this factor is set to another value *f*, ``y(i)`` is compared to the + average multiplied by ``f``. + - *SmoothStrip*: if this parameter is set to ``True``, a smoothing is applied + prior to the strip. + + +These parameters can be modified like this: + +.. code-block:: python + + # ... + fit.settheory('Strip') + fit.configure(StripWidth=5, + StripNIterations=5000, + StripThresholdFactor=1.1, + SmoothStrip=True) + # ... + +Using a strip background has performance implications. You should try to keep +the number of iterations as low as possible if you need to run batch fitting +using this model. Increasing the strip width can help reducing the number of +iterations, with the risk of underestimating the background signal. + +.. _fitwidget-tutorial: + +Using :class:`FitWidget` +++++++++++++++++++++++++ + +.. currentmodule:: silx.gui.fit.FitWidget + +Simple usage +************ + +The :class:`FitWidget` is a graphical interface for :class:`FitManager`. + +.. code-block:: python + + import numpy + from silx.gui import qt + from silx.gui.fit import FitWidget + from silx.math.fit.functions import sum_gauss + + x = numpy.arange(2000).astype(numpy.float) + constant_bg = 3.14 + + # gaussian parameters: height, position, fwhm + p = numpy.array([1000, 100., 30.0, + 500, 300., 25., + 1700, 500., 35., + 750, 700., 30.0, + 1234, 900., 29.5, + 302, 1100., 30.5, + 75, 1300., 75.]) + y = sum_gauss(x, *p) + constant_bg + + a = qt.QApplication([]) + + w = FitWidget() + w.setData(x=x, y=y) + w.show() + + a.exec_() + +.. |imgFitWidget1| image:: img/fitwidget1.png + :width: 300px + :align: middle + +.. |imgFitWidget2| image:: img/fitwidget2.png + :width: 300px + :align: middle + +.. |imgFitWidget3| image:: img/fitwidget3.png + :width: 300px + :align: middle + +.. |imgFitWidget4| image:: img/fitwidget4.png + :width: 300px + :align: middle + +Executing this code opens the following widget. + + |imgFitWidget1| + +The functions you can choose from are the standard gaussian-shaped functions +from :mod:`silx.math.fit.fittheories`. At the top of the list, you will find +the *Add Function(s)* option, that allows you to load your user defined fit +theories from a *.py* source file. + +After selecting the *Constant* background model and clicking the *Estimate* +button, the widget displays this: + + |imgFitWidget2| + +The 7 peaks have been detected, and their parameters estimated. +Also, the estimation function defined some constraints (positive height and +positive full-width at half-maximum). + +You can modify the values in the estimation column of the table, to use different +initial parameters for the fit. + +The individual constraints can be modified prior to fitting. It is also possible to +modify the constraints globally by clicking the *Configure* button' to open a +configuration dialog. To get help on the meaning of the various parameters, +hover the mouse on the corresponding check box or entry widget, to display a +tooltip help message. + + |imgFitWidget3| + +The other configuration tabs can be modified to change the peak search parameters +and the strip background parameters prior to the estimation. +After closing the configuration dialog, you must re-run the estimation +by clicking the *Estimate* button. + +After all configuration parameters and all constrants are set according to your +preferences, you can click the *Start Fit* button. This runs the fit and displays +the results in the *Fit Value* column of the table. + + |imgFitWidget4| + +Customizing the functions +************************* + +.. |imgFitWidget5| image:: img/fitwidget5.png + :width: 300px + :align: middle + +The :class:`FitWidget` can be initialized with a non-standard +:class:`FitManager`, to customize the available functions. + +.. code-block:: python + + from silx.gui import qt + from silx.math.fit import FitManager + from silx.gui.fit import FitWidget + + def linearfun(x, a, b): + return a * x + b + + # create synthetic data for the example + x = list(range(0, 100)) + y = [linearfun(x_, 2.0, 3.0) for x_ in x] + + # we need to create a custom fit manager and add our theory + myfitmngr = FitManager() + myfitmngr.setdata(x, y) + myfitmngr.addtheory("my linear function", + function=linearfun, + parameters=["a", "b"]) + + a = qt.QApplication([]) + + # our fit widget can now use our custom fit manager + fw = FitWidget(fitmngr=myfitmngr) + fw.show() + + a.exec_() + +In our previous example, we didn't load a custom :class:`FitManager`. +Therefore, the fit widget automatically initialized a fit manager and +loaded the custom gaussian functions. + +This time, we initialized our own :class:`FitManager` and loaded our +own function, so only this function is presented as an option in the GUI. + +Our custom function does not provide an associated estimation function, so +the default estimation function of :class:`FitManager` was used. This +default estimation function returns an array of ones the same length as the +list of *parameter* names, and set all constraints to *FREE*. + + |imgFitWidget5| diff --git a/doc/source/Tutorials/fitconfig.rst b/doc/source/Tutorials/fitconfig.rst new file mode 100644 index 0000000..1b5e8ae --- /dev/null +++ b/doc/source/Tutorials/fitconfig.rst @@ -0,0 +1,207 @@ +Custom fit configuration widgets +================================ + +The *silx* fit widget allows users to add custom fit theories. +A fit theory consists of several components, such as the model function +to be fitted, an estimation function... + +One of these component is the optional custom configuration widget. +This is the dialog widget that is opened when a user clicks the *Configure* +button next to the drop-down list used to select the fit theory or the +background theory. + +This tutorial explains how to define your own fit configuration widget +for your custom fit theories. + +Prerequisites +-------------- + +This tutorial assumes that you are already familiar with +the standard features of :class:`silx.gui.fit.FitWidget`. +See the :ref:`fitwidget-tutorial` tutorial. + +You should also be familiar with adding custom fit theories. + +You will find documentation about these subjects by clicking the following links: + + - :class:`silx.math.fit.fitmanager` (methods `addtheory` and `addbgtheories`) + - :class:`silx.math.fit.fittheory` + - :class:`silx.math.fit.fittheories` + - :class:`silx.math.fit.bgtheories` + +The widgets we will create in this tutorial are based on the PyQt library. +Some knowledge of *PyQt* is desirable. + + +Basic concepts +-------------- + +Modal window +++++++++++++ + +A fit configuration widget should be a modal dialog window, so that +when a user opens the dialog to modify the configuration, the rest of +the program is frozen until all the configuration parameters are properly +defined. The program usually resumes when the user clicks the *Ok* or the +*Cancel* button in the dialog. + +The widget must implement a number of methods and attributes to be used as a +dialog by FitWidget: + + - standard *QDialog* methods: + + - :meth:`show`: should cause the widget to become visible to the + user) + - :meth:`exec_`: should run while the user is interacting with the + widget, interrupting the rest of the program. It should + typically end (*return*) when the user clicks an *OK* + or a *Cancel* button. + - :meth:`result`: must return ``True`` if the new configuration + is to be accepted (*OK* clicked) or ``False`` if it should be + rejected (*Cancel* clicked) + + - an additional *output* attribute, a dictionary storing configuration parameters + to be interpreted by the corresponding fit theory. + + - an optional *setDefault* method to initialize the + widget values with values in a dictionary passed as a parameter. + This will be executed first. + +The first 3 methods can be automatically defined by inheriting :class:`QDialog`. + +Associate a dialog to a theory +++++++++++++++++++++++++++++++ + +After defining a custom dialog widget, it must be initialized and associated +with a theory. + +A fit theory in :class:`FitWidget` is defined by a name. For example, +one of the default theories is named *"Gaussians"*. +So if you define a configuration dialog :class:`MyGaussianConfigWidget` to define +configuration parameters understood by this theory, you can associate it the following +way. + +.. code-block:: python + + fw = FitWidget() + my_config_widget = MyGaussianConfigWidget(parent=fw) + fw.associateConfigDialog(theory_name="Gaussians", + config_widget=my_config_widget) + + +Example +------- + +The following example defines a very basic configuration dialog widget +with a simple text entry in which the user can type in a floating point value. + +The value is simply saved in a dictionary attribute +:attr:`CustomConfigWidget.output`. *FitWidget* will look-up this dictionary +and pass it to the theory's custom configuration function, :func:`fitconfig`. +The configuration function essentially updates the :const:`CONFIG` dictionary +used by our fit function to scale the *y* values. + +.. code-block:: python + + from silx.gui import qt + from silx.gui.fit import FitWidget + from silx.math.fit.fittheory import FitTheory + from silx.math.fit.fitmanager import FitManager + + app = qt.QApplication([]) + + # default fit configuration + CONFIG = {"scale": 1.0} + + # define custom fit config dialog + class CustomConfigWidget(qt.QDialog): + def __init__(self): + qt.QDialog.__init__(self) + self.setModal(True) + self.scalingFactorEdit = qt.QLineEdit(self) + self.scalingFactorEdit.setToolTip( + "Enter the scaling factor" + ) + self.scalingFactorEdit.setValidator(qt.QDoubleValidator()) + + self.ok = qt.QPushButton("ok", self) + self.ok.clicked.connect(self.accept) + cancel = qt.QPushButton("cancel", self) + cancel.clicked.connect(self.reject) + + layout = qt.QVBoxLayout(self) + layout.addWidget(self.scalingFactorEdit) + layout.addWidget(self.ok) + layout.addWidget(cancel) + + self.old_scale = CONFIG["scale"] + self.output = {} + + def accept(self): + self.output["scale"] = float(self.scalingFactorEdit.text()) + qt.QDialog.accept(self) + + def reject(self): + self.output["scale"] = self.old_scale + qt.QDialog.reject(self) + + # our actual fit model function + def fitfun(x, a, b): + return CONFIG["scale"] * (a * x + b) + + # fit configuration + def fitconfig(scale=None, **kw): + """Update global config dict CONFIG""" + if scale is not None: + CONFIG["scale"] = scale + return CONFIG + + # synthetic test data a=2, b=3 + x = list(range(0, 100)) + y = [fitfun(x_, 2, 3) for x_ in x] + + # register our custom fit theory + fitmngr = FitManager() + fitmngr.setdata(x, y) + fitmngr.addtheory("scaled linear", + FitTheory( + function=fitfun, + parameters=["a", "b"], + configure=fitconfig)) + + # open a fitwidget and associate an instance of our custom + # configuration dialog to our custom theory + fw = FitWidget(fitmngr=fitmngr) + fw.associateConfigDialog("scaled linear", CustomConfigWidget()) + fw.show() + + app.exec_() + +.. |img0| image:: img/custom_config_scale1.0.png + :height: 300px + :align: middle + +.. |img1| image:: img/custom_config_scale2.1.png + :height: 300px + :align: middle + +.. |img2| image:: img/custom_config_scale0.5.png + :height: 300px + :align: middle + + +.. list-table:: + :widths: 1 4 + :header-rows: 1 + + * - Screenshot + - Description + * - |img0| + - If the default value of 1.0 is used, the fit finds *a=2* and *b=3* + as expected. + * - |img1| + - Setting a scaling factor of 2.1 causes the fit to find results that are + less than about half of the normal expected result. + * - |img2| + - A scaling factor of 0.5 causes the fit to find the values to be double + of the ones used for generating the synthetic data. diff --git a/doc/source/Tutorials/img/arraywidget3D_0.png b/doc/source/Tutorials/img/arraywidget3D_0.png new file mode 100644 index 0000000..0b654d7 Binary files /dev/null and b/doc/source/Tutorials/img/arraywidget3D_0.png differ diff --git a/doc/source/Tutorials/img/arraywidget3D_1.png b/doc/source/Tutorials/img/arraywidget3D_1.png new file mode 100644 index 0000000..fb55827 Binary files /dev/null and b/doc/source/Tutorials/img/arraywidget3D_1.png differ diff --git a/doc/source/Tutorials/img/arraywidget5D_0.png b/doc/source/Tutorials/img/arraywidget5D_0.png new file mode 100644 index 0000000..11a56de Binary files /dev/null and b/doc/source/Tutorials/img/arraywidget5D_0.png differ diff --git a/doc/source/Tutorials/img/arraywidget5D_1.png b/doc/source/Tutorials/img/arraywidget5D_1.png new file mode 100644 index 0000000..817b507 Binary files /dev/null and b/doc/source/Tutorials/img/arraywidget5D_1.png differ diff --git a/doc/source/Tutorials/img/custom_config_scale0.5.png b/doc/source/Tutorials/img/custom_config_scale0.5.png new file mode 100644 index 0000000..58d4665 Binary files /dev/null and b/doc/source/Tutorials/img/custom_config_scale0.5.png differ diff --git a/doc/source/Tutorials/img/custom_config_scale1.0.png b/doc/source/Tutorials/img/custom_config_scale1.0.png new file mode 100644 index 0000000..9dc9462 Binary files /dev/null and b/doc/source/Tutorials/img/custom_config_scale1.0.png differ diff --git a/doc/source/Tutorials/img/custom_config_scale2.1.png b/doc/source/Tutorials/img/custom_config_scale2.1.png new file mode 100644 index 0000000..d1d3663 Binary files /dev/null and b/doc/source/Tutorials/img/custom_config_scale2.1.png differ diff --git a/doc/source/Tutorials/img/fitwidget1.png b/doc/source/Tutorials/img/fitwidget1.png new file mode 100644 index 0000000..be371ac Binary files /dev/null and b/doc/source/Tutorials/img/fitwidget1.png differ diff --git a/doc/source/Tutorials/img/fitwidget2.png b/doc/source/Tutorials/img/fitwidget2.png new file mode 100644 index 0000000..5ee43bb Binary files /dev/null and b/doc/source/Tutorials/img/fitwidget2.png differ diff --git a/doc/source/Tutorials/img/fitwidget3.png b/doc/source/Tutorials/img/fitwidget3.png new file mode 100644 index 0000000..5da223c Binary files /dev/null and b/doc/source/Tutorials/img/fitwidget3.png differ diff --git a/doc/source/Tutorials/img/fitwidget4.png b/doc/source/Tutorials/img/fitwidget4.png new file mode 100644 index 0000000..feff3a2 Binary files /dev/null and b/doc/source/Tutorials/img/fitwidget4.png differ diff --git a/doc/source/Tutorials/img/fitwidget5.png b/doc/source/Tutorials/img/fitwidget5.png new file mode 100644 index 0000000..1e1278f Binary files /dev/null and b/doc/source/Tutorials/img/fitwidget5.png differ diff --git a/doc/source/Tutorials/img/stripbg_plot1.png b/doc/source/Tutorials/img/stripbg_plot1.png new file mode 100644 index 0000000..260890e Binary files /dev/null and b/doc/source/Tutorials/img/stripbg_plot1.png differ diff --git a/doc/source/Tutorials/img/stripbg_plot2.png b/doc/source/Tutorials/img/stripbg_plot2.png new file mode 100644 index 0000000..70e2ca2 Binary files /dev/null and b/doc/source/Tutorials/img/stripbg_plot2.png differ diff --git a/doc/source/Tutorials/specfile_to_hdf5.rst b/doc/source/Tutorials/specfile_to_hdf5.rst new file mode 100644 index 0000000..31f8383 --- /dev/null +++ b/doc/source/Tutorials/specfile_to_hdf5.rst @@ -0,0 +1,323 @@ + +SpecFile as HDF5 +================ + +Introduction to SPEC data files +------------------------------- + +SPEC data files are ASCII files. +They contain two general types of block of lines: + + - header lines starting with a ``#`` immediately followed by one or more characters + identifying the information that follows + - data lines + +Header lines +++++++++++++ + +There are two types of headers. The first type is the *file header*. File headers always start +with a ``#F`` line. +The metadata stored in a file header applies to all the content of the data file, until a +new file header is encountered. There can be more than one file header, but a file with +multiple headers can be treated as multiple SPEC files concatenated into a single one. +File headers are sometimes missing. + +A file header contains general information: + + - ``#F`` - file name + - ``#E`` - epoch + - ``#D`` - file time and date + - ``#C`` - First comment (SPEC title, SPEC user) + - ``#O`` - Motor names (separated by at least two blank spaces) + +The second type of header is the *scan header*. A scan header must start with a ``#S`` line +and must be preceded by an empty line. This also applies to files without file headers: in +such a case, the file must start with an empty line. +The metadata stored in scan headers applies to a single block of data lines. + +A scan header contains following information: + + - ``#S`` - Mandatory first line showing the scan number and the + command that was used to record the scan + - ``#D`` - scan time and date + - ``#Q`` - *H, K, L* values + - ``#P`` - Motor positions (corresponding motor names are in file header ``#O``) + - ``#N`` - Number of data columns in the following data block + - ``#L`` - Column labels (``#N`` labels separated by two blank spaces) + +Users can also define their own type of header lines in their macros. + +There can sometimes be a block of scan header lines after a data block, but before the ``#S`` of the next +scan. + +Data lines +++++++++++ + +Data blocks are structured as 2D arrays. Each line contains ``#N`` values, each value +corresponding to the label with the same position in the ``#L`` scan header line. +This implies that each column corresponds to one series of measurements. + +A column typically contains motor positions for a given positioner, a timestamp or the measurement +of a sensor. + +MCA data +++++++++ + +Newer SPEC files can also contain multi-channel analyser data, in between each *normal* data line. +A multichannel analyser records multiple values per single measurement. +This is typically a histogram of number of counts against channels (*MCA spectrum*), to analyze energy distribution +of a process. + +SPEC data files containing MCA data have additional scan header lines: + + - ``#@MCA %16C`` - a spectrum will usually extend for more than one line. + This indicates a number of 16 values per line. + - ``#@CHANN`` - contains 4 values: + + - the number of channels per spectrum + - the first channel number + - the last channel number + - the increment between two channel numbers (usually 1) + - ``#@CALIB`` - 3 polynomial calibration values a, b, c. ( i.e. energy = a + b * channel + c * channel ^ 2) + - ``#@CTIME`` - 3 values: preset time, live time, elapsed time + +The actual MCA data for a single spectrum usually spans over multiple lines. +A spectrum starts on a new line with a ``@A``, and when it span over multiple lines, all +lines except the last one end with a continuation character ``\``. + +Example of SPEC file +++++++++++++++++++++ + +Example of file header:: + + #F ./data/binary_mixtures_mca1.100211 + #E 1295362398 + #D Thu Feb 10 22:43:43 2011 + #C id10b User = opid10 + #O0 delta gamma omega theta mu sigma sigmat xt + #O1 zt zt1 thd chid rhod xd yd zd + #O2 att0 arcf zf PhiD phigH chigH ygH + #O3 zgH phigV chigV xgV ygV zgV gslithg gslitho + #O4 gslitvo gslitvg slit1T slit1B slit1F slit1R slit1hg slit1ho + #O5 slit1vg slit1vo s0T s0B s0R s0F + #O6 s0hg s0ho s0vg s0vo TRT + #O7 pi trough hv1 mpxthl apdwin apdthl apdhv xcrl2 + #O8 thcrl2 zcrl2 picou picod vdrift vmulti vglo vghi + #O9 rien + +Example of scan and data block, without MCA:: + + #S 30 ascan tz3 29.35 29.75 100 0.5 + #D Sat Oct 31 15:43:21 1998 + #T 0.5 (Seconds) + #G0 0 + #G1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + #G2 0 + #Q + #P0 40.135381 40.262001 65.6 70 35 -1.83 0 -36.1 + #P1 0 0 -1.98 0 0 35.6 86.2 -29.5 + #P2 3.0688882 24.893749 295.98749 28 -27.249938 + #N 22 + #L TZ3 Epoch Seconds If2 If3 If5 If6 If7 If8 I0 It ItdI0 If1dI0 If2dI0 If3dI0 If4dI0 If5dI0 If6dI0 If7dI0 If8dI0 If1 If4 + 29.35 45246 0.000264 478 302 206 201 209 264 177860 646 0.00363207 0.00468346 0.00268751 0.00169796 0.00146745 0.00115821 0.0011301 0.00117508 0.00148431 833 261 + 29.353976 45249 0.000295 549 330 219 208 227 295 178021 684 0.00384224 0.00537577 0.00308391 0.00185371 0.00158408 0.00123019 0.0011684 0.00127513 0.00165711 957 282 + 29.357952 45251 0.000313 604 368 231 215 229 313 178166 686 0.00385034 0.00603931 0.0033901 0.00206549 0.00166698 0.00129654 0.00120674 0.00128532 0.00175679 1076 297 + 29.362028 45253 0.000333 671 390 237 226 236 333 178387 672 0.00376709 0.00683346 0.00376148 0.00218626 0.00176582 0.00132857 0.00126691 0.00132297 0.00186673 1219 315 + 29.366004 45256 0.000343 734 419 248 229 236 343 178082 664 0.00372862 0.00765939 0.0041217 0.00235285 0.00185308 0.00139262 0.00128592 0.00132523 0.00192608 1364 330 + 29.36998 45258 0.00036 847 448 254 229 248 360 178342 668 0.00374561 0.00857342 0.0047493 0.00251203 0.00194009 0.00142423 0.00128405 0.00139059 0.00201859 1529 346 + +Synthetic example of file with 3 scans. The last scan includes data of 3 multichannel analysers, sharing the +same MCA header. + +:: + + #F /tmp/sf.dat + #E 1455180875 + #D Thu Feb 11 09:54:35 2016 + #C imaging User = opid17 + #O0 Pslit HGap MRTSlit UP MRTSlit DOWN + #O1 Sslit1 VOff Sslit1 HOff Sslit1 VGap + #o0 pshg mrtu mrtd + #o2 ss1vo ss1ho ss1vg + + #S 1 ascan ss1vo -4.55687 -0.556875 40 0.2 + #D Thu Feb 11 09:55:20 2016 + #T 0.2 (Seconds) + #P0 180.005 -0.66875 0.87125 + #P1 14.74255 16.197579 12.238283 + #N 3 + #L MRTSlit UP second column 3rd_col + -1.23 5.89 8 + 8.478100E+01 5 1.56 + 3.14 2.73 -3.14 + 1.2 2.3 3.4 + + #S 25 ascan c3th 1.33245 1.52245 40 0.15 + #D Sat 2015/03/14 03:53:50 + #P0 80.005 -1.66875 1.87125 + #P1 4.74255 6.197579 2.238283 + #N 4 + #L column0 column1 col2 col3 + 0.0 0.1 0.2 0.3 + 1.0 1.1 1.2 1.3 + 2.0 2.1 2.2 2.3 + 3.0 3.1 3.2 3.3 + + #S 1 aaaaaa + #D Thu Feb 11 10:00:32 2016 + #@MCA %16C + #@CHANN 20 0 19 1 + #@CALIB 1.2 2.3 3.4 + #@CTIME 123.4 234.5 345.6 + #N 2 + #L uno duo + 1 2 + @A 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15\ + 16 17 18 19 + 3 4 + @A 0 0 2 4 15 10 5 1 0 0 0 0 1 0 0 0\ + 0 0 0 0 + 5 6 + @A 0 0 0 0 5 7 2 0 0 0 0 0 1 0 0 0\ + 0 0 0 1 + +Reading a SpecFile as an HDF5 file +---------------------------------- + +Introduction to the spech5 module ++++++++++++++++++++++++++++++++++ + +The *silx* module :mod:`silx.io.spech5` can be used to expose SPEC files in a hierarchical tree structure +and access them through an API that mimics the *h5py* Python library used to read HDF5 files. + +The structure exposed is as follows:: + + / + 1.1/ + title = "…" + start_time = "…" + instrument/ + specfile/ + file_header = ["…", "…", …] + scan_header = ["…", "…", …] + positioners/ + motor_name = value + … + mca_0/ + data = … + calibration = … + channels = … + preset_time = … + elapsed_time = … + live_time = … + + mca_1/ + … + … + measurement/ + colname0 = … + colname1 = … + … + mca_0/ + data -> /1.1/instrument/mca_0/data + info -> /1.1/instrument/mca_0/ + … + 2.1/ + … + +Scans appear as *Groups* at the root level. The name of a scan group is +made of two numbers, the first one being the *scan number* from the ``#S`` +header line, and the second one being the *scan order*. +If a scan number appears multiple times in a SPEC file, the scan order is incremented. +For examples, the scan *3.2* designates the second occurence of scan number 3 in a given file. + +Data is stored in the ``measurement`` subgroup, one dataset per column. The dataset name +is the column label as it appears on the ``#L`` header line. + +The ``instrument`` subgroup contains following subgroups: + + - ``specfile`` - contains two datasets, ``file_header`` and ``scan_header``, + containing all header lines as a long string. Lines are delimited by the ``\n`` character. + - ``positioners`` - contains one dataset per motor (positioner), containing + either the single motor position from the ``#P`` header line, or a complete 1D array + of positions if the motor names corresponds to a data column (i.e. if the motor name + from the ``#O`` header line is identical to a label on the ``#L`` header line) + - one subgroup per MCA analyser/device containing a 2D ``data`` array with all spectra + recorded by this analyser, as well as datasets for the various MCA metadata + (``#@`` header lines). The first dimension of the ``data`` array corresponds to the number + of points and the second one to the spectrum length. + + +In addition the the data columns, this group contains one subgroup per MCA analyser/device +with links to the data already contained in ``instrument/mca_...`` + +spech5 examples ++++++++++++++++ + +Accessing groups and datasets: + +.. code-block:: python + + from silx.io.spech5 import SpecH5 + + # Open a SpecFile + sfh5 = SpecH5("test.dat") + + # using SpecH5 as a regular group to access scans + scan1group = sfh5["1.1"] # This retrieves scan 1.1 + scan1group = sfh5[0] # This retrieves the first scan irrespectively of its number. + instrument_group = scan1group["instrument"] + + # alternative: full path access + measurement_group = sfh5["/1.1/measurement"] + + # accessing a scan data column by name as a 1D numpy array + data_array = measurement_group["Pslit HGap"] + + # accessing all mca-spectra for one MCA device as a 2D array + mca_0_spectra = measurement_group["mca_0/data"] + + +Files and groups can be treated as iterators, which allows looping through them. + +.. code-block:: python + + # get all column names (labels) in all scans in a file + for scan_group in SpecH5("test.dat"): + dataset_names = [item.name in scan_group["measurement"] if not + item.name.startswith("mca")] + print("Found labels in scan " + scan_group.name + " :") + print(", ".join(dataset_names)) + +Converting SPEC data to HDF5 +++++++++++++++++++++++++++++ + +The *silx* module :mod:`silx.io.spectoh5` can be used to convert a SPEC file into a +HDF5 file with the same structure as the one exposed by the :mod:`spech5` module. + +.. code-block:: python + + from silx.io.spectoh5 import convert + + convert("/home/pierre/myspecfile.dat", "myfile.h5") + + +You can then read the file with any HDF5 reader. + + +In addition to the function :func:`silx.io.spectoh5.convert`, which is simplified +on purpose, you can use the more flexible :func:`silx.io.spectoh5.write_spec_to_h5`. + +This way, you can choose to write scans into a specific HDF5 group in the output directory. +You can also decide whether you want to overwrite an existing file, or append data to it. +You can specify whether existing data with the same name as input data should be overwritten +or ignored. + +This allows you to repeatedly transfer new content of a SPEC file to an existing HDF5 file, in between +two scans. + +The following script is an example of a command line interface to :func:`write_spec_to_h5`. + +.. literalinclude:: ../../../examples/spectoh5.py + :lines: 42- + diff --git a/doc/source/changelog.rst b/doc/source/changelog.rst new file mode 100644 index 0000000..09929fe --- /dev/null +++ b/doc/source/changelog.rst @@ -0,0 +1 @@ +.. include:: ../../CHANGELOG.rst diff --git a/doc/source/conf.py b/doc/source/conf.py new file mode 100644 index 0000000..30abf54 --- /dev/null +++ b/doc/source/conf.py @@ -0,0 +1,255 @@ +# -*- coding: utf-8 -*- +# +# silx documentation build configuration file, created by +# sphinx-quickstart on Fri Nov 27 14:20:46 2015. +# +# This file is execfile()d with the current directory set to its containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys +import os +import glob +import subprocess + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# sys.path.insert(0, os.path.abspath('.')) +dirname = os.path.dirname +root_dir = dirname(dirname(dirname(os.path.abspath(__file__)))) +import silx +source_dir = dirname(dirname(silx.__file__)) +os.environ["PYTHONPATH"] = source_dir + os.pathsep + os.environ.get("PYTHONPATH", "") + +# -- General configuration ----------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.coverage', + 'sphinx.ext.mathjax', + 'sphinx.ext.viewcode', + 'sphinx.ext.doctest' +] + +autodoc_member_order = 'bysource' + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +# source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'silx' +from silx._version import strictversion, version, __date__ as _date +year = _date.split("/")[-1] +copyright = u'2015-%s, Data analysis unit, European Synchrotron Radiation Facility, Grenoble' % year + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +# version = '0.0.1' +# The full version, including alpha/beta/rc tags. +release = strictversion + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +# today = '' +# Else, today_fmt is used as the format for a strftime call. +# today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = [] + +# The reST default role (used for this markup: `text`) to use for all documents. +# default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +# add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +# add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +# show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +# modindex_common_prefix = [] + + +# -- Options for HTML output --------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'default' + +# 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 = {} + +# Add any paths that contain custom themes here, relative to this directory. +# html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +# html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +# html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +html_logo = "img/silx_small.png" + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +html_favicon = "img/silx.ico" + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +# html_static_path = ['_static'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +# html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +# html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +# html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +# html_additional_pages = {} + +# If false, no module index is generated. +# html_domain_indices = True + +# If false, no index is generated. +# html_use_index = True + +# If true, the index is split into individual pages for each letter. +# html_split_index = False + +# If true, links to the reST sources are added to the pages. +# html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +# html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is 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 +# base URL from which the finished HTML is served. +# html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +# html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'silxdoc' + + +# -- Options for LaTeX output -------------------------------------------------- + +latex_elements = {'papersize': 'a4paper', + 'pointsize': '10pt'} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +latex_documents = [ + ('index', 'silx.tex', u'silx Documentation', + u'Data analysis unit', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +latex_logo = "img/silx_large.png" + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +# latex_use_parts = False + +# If true, show page references after internal links. +# latex_show_pagerefs = False + +# If true, show URL addresses after external links. +# latex_show_urls = False + +# Documents to append as an appendix to all manuals. +# latex_appendices = [] + +# If false, no module index is generated. +# latex_domain_indices = True + + +# -- Options for manual page output -------------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'silx', u'silx Documentation', + [u'Data analysis unit'], 1) +] + +# If true, show URL addresses after external links. +# man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------------ + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ('index', 'silx', u'silx Documentation', + u'Data analysis unit', 'silx', 'One line description of project.', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +# texinfo_appendices = [] + +# If false, no module index is generated. +# texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +# texinfo_show_urls = 'footnote' + +# Do not test code in >>> by default +doctest_test_doctest_blocks = '' diff --git a/doc/source/description/img/sift_bench_cpu0.png b/doc/source/description/img/sift_bench_cpu0.png new file mode 100644 index 0000000..63d1295 Binary files /dev/null and b/doc/source/description/img/sift_bench_cpu0.png differ diff --git a/doc/source/description/img/sift_bench_cpu_kp.png b/doc/source/description/img/sift_bench_cpu_kp.png new file mode 100644 index 0000000..30ca3ad Binary files /dev/null and b/doc/source/description/img/sift_bench_cpu_kp.png differ diff --git a/doc/source/description/img/sift_bench_cpu_res.png b/doc/source/description/img/sift_bench_cpu_res.png new file mode 100644 index 0000000..3fc8758 Binary files /dev/null and b/doc/source/description/img/sift_bench_cpu_res.png differ diff --git a/doc/source/description/img/sift_bench_gpu0.png b/doc/source/description/img/sift_bench_gpu0.png new file mode 100644 index 0000000..f41a35d Binary files /dev/null and b/doc/source/description/img/sift_bench_gpu0.png differ diff --git a/doc/source/description/img/sift_bench_gpu_kp.png b/doc/source/description/img/sift_bench_gpu_kp.png new file mode 100644 index 0000000..c649a3b Binary files /dev/null and b/doc/source/description/img/sift_bench_gpu_kp.png differ diff --git a/doc/source/description/img/sift_bench_gpu_res.png b/doc/source/description/img/sift_bench_gpu_res.png new file mode 100644 index 0000000..f3d1cf1 Binary files /dev/null and b/doc/source/description/img/sift_bench_gpu_res.png differ diff --git a/doc/source/description/img/sift_dog1.png b/doc/source/description/img/sift_dog1.png new file mode 100644 index 0000000..634a1d2 Binary files /dev/null and b/doc/source/description/img/sift_dog1.png differ diff --git a/doc/source/description/img/sift_match1.png b/doc/source/description/img/sift_match1.png new file mode 100644 index 0000000..3091dfc Binary files /dev/null and b/doc/source/description/img/sift_match1.png differ diff --git a/doc/source/description/img/sift_orientation.png b/doc/source/description/img/sift_orientation.png new file mode 100644 index 0000000..eb19947 Binary files /dev/null and b/doc/source/description/img/sift_orientation.png differ diff --git a/doc/source/description/index.rst b/doc/source/description/index.rst new file mode 100644 index 0000000..4fe7d4c --- /dev/null +++ b/doc/source/description/index.rst @@ -0,0 +1,9 @@ +Description +=========== + +This section contains the description of the implementation of the algorithms: + +.. toctree:: + :maxdepth: 1 + + sift.rst diff --git a/doc/source/description/sift.rst b/doc/source/description/sift.rst new file mode 100644 index 0000000..bd89dd0 --- /dev/null +++ b/doc/source/description/sift.rst @@ -0,0 +1,399 @@ +General introduction to sift. +============================= + +silx.image.sift, a parallel version of SIFT algorithm +----------------------------------------------------- + +SIFT (Scale-Invariant Feature Transform) is an algorithm developed by David Lowe in 1999. +It is a worldwide reference for image alignment and object recognition. +The robustness of this method enables to detect features at different scales, +angles and illumination of a scene. +The implementation available in silx uses OpenCL, meaning that it can run on +Graphics Processing Units and Central Processing Units as well. +Interest points are detected in the image, then data structures called +*descriptors* are built to be characteristic of the scene, so that two different +images of the same scene have similar descriptors. They are robust to transformations +like translation, rotation, rescaling and illumination change, which make SIFT +interesting for image stitching. +In the fist stage, descriptors are computed from the input images. +Then, they are compared to determine the geometric transformation to apply in +order to align the images. +silx.image.sift can run on most graphic cards and CPU, making it usable on many setups. +OpenCL processes are handled from Python with PyOpenCL, a module to access OpenCL parallel computation API. + + +Introduction +------------ + +The European Synchrotron Radiation Facility (ESRF) beamline ID21 developed a +full-field method for X-ray absorption near-edge spectroscopy (XANES). +Since the flat field images are not acquired simultaneously with the sample +transmission images, a realignment procedure has to be performed. +Serial SIFT implementation used to take about 8 seconds per frame, and one stack +can have up to 500 frames. +It is a bottleneck in the global process, therefore a parallel version had to be implemented. +silx.image.sift differs from existing parallel implementations of SIFT in the way +that the whole process is done on the device, enabling crucial speed-ups. + + +Launching silx.image.sift +------------------------- + +silx.image.sift is written in Python, and handles the OpenCL kernels with PyOpenCL. +This enables a simple and efficient access to GPU resources. +The project is installed as a Python library and can be imported in a script. + +Before image alignment, points of interest (keypoints) have to be detected in each image. +The whole process can be launched by several lines of code. + + +How to use it +............. + +silx.image.sift is installed as part of silx and requires PyOpenCL to be useable. +It generates a library that can be imported, then used to compute a list of descriptors from an image. +The image can be in RGB values, but all the process is done on grayscale values. +One can specify the devicetype, either CPU or GPU. + +.. Although being integrated in ESRF EDNA framework for online image alignment, + and thus mostly used by developers, silx.image.sift provides example scripts. + + .. code-block:: python + + #TODO: update + python test/demo.py --type=GPU my_image.jpg + +This computes and shows the keypoints on the input image. +One can also launch silx.image.sift interactively with iPython : + +.. code-block:: python + + from silx.image import sift + import numpy + import scipy.misc + image_rgb = scipy.misc.imread("my_image.jpg") + sift_ocl = sift.SiftPlan(template=image_rgb, devicetype="GPU") + kp = sift_ocl.keypoints(image_rgb) + print(kp[-1]) + + +silx.image.sift files +..................... + +The Python sources are in the ``silx.image.sift`` module: + +.. code-block:: python + + from silx.image import sift + print(sift.__file__) + +The file ``plan.py`` corresponds to the keypoint extraction and handles the whole process: +from kernel compilation to descriptors generation as numpy array. +The OpenCL kernels are distributed as *resources* in the "openCL" folder; they are compiled on the fly. +Several kernels have multiple implementations, depending the architecture to run on. + +The file ``match.py`` does the matching between two lists of keypoints returned by ``plan.py``. + +The file ``alignment.py`` does the image alignment : it computes the keypoints +from two images (``plan.py``), then uses the matching result (``match.py``) +to find out the transformation aligning the second image on the first. + +Each of those module contain a class which holds GPU contexts, memory and kernel. +They are expensive to instantiate and should be re-used as much as possible. + +Overall process +*************** + +The different steps of SIFT are handled by ``plan.py``. +When launched, it automatically choose the best device to run on, unless a device +is explicitly provided in the options. +All the OpenCL kernels that can be compiled are built on the fly. +Buffers are pre-allocated on the device, and all the steps are executed on rge device (GPU). +At each *octave* (scale level), keypoints are returned to the CPU and the buffers are re-used. + +Once the keypoints are computed, the keypoints of two different images can be compared. +This matching is done by ``match.py``. +It simply takes the descriptors of the two lists of keypoints, and compare them with a L1 distance. +It returns a vector of *matchings*, i.e couples of similar keypoints. + +For image alignment, ``alignment.py`` takes the matching vector between two images +and determines the transformation to be done in order to align the second image on the first. + + +SIFT keypoints computation +-------------------------- + +The keypoints are detected in several steps according to Lowe's paper_ : + +.. _paper: http://www.cs.ubc.ca/~lowe/papers/ijcv04.pdf + +* Keypoints detection: local extrema are detected in the *scale-space* :math:`(x, y, s)`. + Every pixel is compared to its neighborhood in the image itself, + and in the previous/next scale factor images. +* Keypoints refinement: keypoints located on corners are discarded. + Additionally, a second-order interpolation is done to improve the keypoints + accuracy, modifying the coordinates :math:`(x, y, s)`. +* Orientation assignment: a characteristic orientation is assigned to the + keypoints :math:`(x,y,s, \theta)` +* Descriptor computation: a histogram of orientations is built around every keypoint, + then concatenated in a 128-values vector. + This vector is called *SIFT descriptor*, it is robust to rotation, illumination, translation and scaling. + +The scale variation is simulated by blurring the image. +A very blurred image represents a scene seen from a distance, for small details are not visible. + + +Unlike existing parallel versions of SIFT, the entire process is done on the +device to avoid time-consuming transfers between CPU and GPU. +This leads to several tricky parts like the use of atomic instructions, or +writing different versions of the same kernel to adapt to every platform. + + + +Keypoints detection +................... + +The image is increasingly blurred to imitate the scale variations. +This is done by convolving with a gaussian kernel. +Then, consecutive blurs are subtracted to get *differences of gaussians (DoG)*. +In these DoG, every pixel is tested. Let :math:`(x,y)` be the pixel position in +the current (blurred) image, and :math:`s` its *scale* (that is, the blur factor). +The point :math:`(x,y,s)` is a local maximum in the scale-space if + +* :math:`D(x-1, y, s) < D(x,y,s)` and :math:`D(x,y,s) > D(x+1, y, s)` (local maximum in :math:`x`) +* :math:`D(x, y-1, s) < D(x,y,s)` and :math:`D(x,y,s) > D(x, y+1, s)` (local maximum in :math:`y`) +* :math:`D(x, y, s -1) < D(x,y,s)` and :math:`D(x,y,s) > D(x, y, s+1)` (local maximum in :math:`s`) + + +.. figure:: img/sift_dog1.png + :align: center + :alt: detection in scale-space + + +For these steps, we highly benefit from the parallelism : every pixel is handled +by a GPU thread. +Besides, convolution is implemented in the direct space (without Fourier Transform) +and is quite fast (50 times faster than the convolutions done by the C++ reference +implementation). + + +Keypoints refinement +.................... + +At this stage, many keypoints are not reliable. Low-contrast keypoints are discarded, +and keypoints located on an edge are rejected as well. +For keypoints located on an edge, principal curvature across the edge is much larger +than the principal curvature along it. Finding these principal curvatures amounts +to solving for the eigenvalues of the second-order Hessian matrix of the current DoG. +The ratio of the eigenvalues :math:`r` is compared to a threshold :math:`\dfrac{(r+1)^2}{r} < R` +with R defined by taking r=10. + +To improve keypoints accuracy, the coordinates are interpolated with a second-order Taylor development. + + .. math:: + + D \left( \vec{x} + \vec{\delta_x} \right) \simeq D + \dfrac{\partial D}{\partial \vec{x}} \cdot \vec{\delta_x} + \dfrac{1}{2} \left( \vec{\delta_x} \right)^T \cdot \left( H \right) \cdot \vec{\delta_x} \qquad \text{with } H = \dfrac{\partial^2 D}{\partial \vec{x}^2} + +Keypoints that were too far from a *true* (interpolated) extremum are rejected. + + + +Orientation assignment +...................... + +An orientation has to be assigned to each keypoint so that SIFT descriptors will +be invariant to rotation. For each blurred version of the image, the gradient +magnitude and orientation are computed. +From the neighborhood of a keypoint, a histogram of orientations is built +(36 bins, 1 bin per 10 degrees). + +.. figure:: img/sift_orientation.png + :align: center + :alt: orientation assignment + +The maximum value of this histogram is the dominant orientation ; it is defined +as the characteristic orientation of the keypoint. +Additionally, every peak greater than 80% of the maximum generates a new +keypoint with a different orientation. + +The parallel implementation of this step is complex, and the performances strongly +depend on the graphic card the program is running on. +That is why there are different files for this kernel, adapted for different platforms. +The file to compile is automatically determined in ``plan.py``. + + +Descriptor computation +...................... + +A histogram of orientations is built around every keypoint. +The neighborhood is divided into 4 regions of 4 sub-regions of 4x4 pixels. +In every sub-region, a 8-bin histogram is computed; then, all the histograms are +concatenated in a 128-values descriptor. +The histogram is weighted by the gradient magnitudes and the current scale factor, +so that the descriptor is robust to rotation, illumination, translation and scaling. +Here again, there are several files adapted to different platforms. + + +Image matching and alignment +---------------------------- + +Matching is also explained in this tutorial, once the keypoints are + + + +.. figure:: img/sift_match1.png + :align: center + :alt: Example of image matching for pattern recognition + + +.. figure:: img/sift_match2.jpg + :align: center + :alt: Another example of image matching for pattern recognition + + +Performances +------------ + +The aim of silx.image.sift is to fasten the SIFT keypoint extraction by running it on GPU. +On big images with many keypoints, it enables a speed-up between 30 and 50 times. +The following benchmark was done on an Intel Xeon E5-2667 (2.90GHz, 2x6 cores) +CPU, and a NVidia Tesla K20m GPU. + + +.. figure:: img/sift_bench_gpu0.png + :align: center + :alt: Benchmark GPU vs CPU + +silx.image.sift can also be run on CPU, even running up to 10 times faster than the C++ implementation. + +.. figure:: img/sift_bench_cpu0.png + :align: center + :alt: Benchmark on CPU : OpenCL implementation vs C++ implementation + + + +SIFT parameters +--------------- + +Command line parameters +....................... + +When launched from the command line, silx.image.sift can handle several options +like the device to run on and the *number of pixels per keypoint*. +By default ``PIX_PER_KP`` is 10, meaning that we gess one keypoint will be found +for every 10 pixels. +This is for buffers allocation on the device, as the number of keypoints that +will be found is unknown, and strongly depends of the type of image. +10 pixels per keypoint is a high estimation, even for images with many features +like landscapes. +For example, this 5.8 MPixels image_ gives about 2500 keypoints, which makes +2270 pixels per keypoints. + +.. _image: http://www.lightsources.org/imagebank/image/esr032 + +If you have big images with few features and the image does not fit on the GPU, +you can increase ``PIX_PER_KP`` in the command line options in order to +decrease the amount of memory required. + + +Advanced SIFT parameters +........................ + +The file ``param.py`` contains SIFT default parameters, recommended by +David Lowe in his paper_ or by the authors of the C++ version in ASIFT_. +You should not modify these values unless you know what you are doing. +Some parameters require to understand several aspects of the algorithm, +explained in Lowe's original paper. + +.. _ASIFT: http://www.ipol.im/pub/art/2011/my-asift + + +``DoubleImSize`` (0 by default) is for the pre-blur factor of the image. +At the beginning, the original image is blurred (*prior-smoothing*) to eliminate noise. +The standard deviation of the gaussian filter is either ``1.52`` if DoubleImSize is 0, or ``1.25`` if DoubleImSize is 1. +Setting this parameter to 1 decrease the prior-smoothing factor, the algorithm will certainly find more keypoints but less accurate. + +``InitSigma`` (1.6 by default) is the prior-smoothing factor. +The original image is blurred by a gaussian filter which standard deviation is +:math:`\sqrt{\text{InitSigma}^2 - c^2}`. +with ``c == 0.5`` if ``DoubleImSize == 0`` or ``c == 1`` otherwise. +If the prior-smoothing factor is decreased, the algorithm will certainly find more +keypoint, but they will be less accurate. + +``BorderDist`` (5 by default) is the minimal distance to borders: +pixels that are less than ``BorderDist`` pixels from the border will be ignored +for the processing. +If features are likely to be near the borders, decreasing this parameter will +enable to detect them. + +``Scales`` (3 by default) is the number of Difference of Gaussians (DoG) that will +actually be used for keypoints detection. +In the gaussian pyramid, Scales+3 blurs are made, from which Scales+2 DoGs are computed. +The DoGs in the middle are used to detect keypoints in the scale-space. +If ``Scales`` is 3, there will be 6 blurs and 5 DoGs in an octave, and 3 DoGs +will be used for local extrema detection. +Increasing Scales will make more blurred images in an octave, so SIFT can detect +a few more strong keypoints. +However, it will slow down the execution for few additional keypoints. + +``PeakThresh`` (255 * 0.04/3.0 by default) is the grayscale threshold for keypoints +refinement. +To discard low-contrast keypoints, every pixel which grayscale value is below +this threshold can not become a keypoint. +Decreasing this threshold will lead to a larger number of keypoints, which can +be useful for detecting features in low-contrast areas. + +``EdgeThresh`` (0.06 by default) and ``EdgeThresh1`` (0.08 by default) are the +limit ratio of principal curvatures while testing if keypoints are located on an edge. +Those points are not reliable for they are sensivite to noise. +For such points, the principal curvature across the edge is much larger than the +principal curvature along it. +Finding these principal curvatures amounts to solving for the eigenvalues of the +second-order Hessian matrix of the current DoG. +The ratio of the eigenvalues :math:`r` is compared to a threshold :math:`\dfrac{(r+1)^2}{r} < R` +with R defined by taking r=10, which gives +:math:`\frac{(r+1)^2}{r} = 12.1`, and 1/12.1 = 0.08. +In the first octave, the value 0.06 is taken instead of 0.08. +Decreasing these values lead to a larger number of keypoints, but sensivite to +noise because they are located on edges. + +``OriSigma`` (1.5 by default) is related to the radius of gaussian weighting in +orientation assignment. +In this stage, for a given keypoint, we look in a region of radius +:math:`3 \times s \times \text{OriSigma}` with :math:`s` the scale of the current keypoint. +Increasing it will not lead to increase the number of keypoints found; +it will take a larger area into account while computing the orientation assignment. +Thus, the descriptor will be characteristic of a larger neighbourhood. + +``MatchRatio`` (0.73 by default) is the threshold used for image alignment. +Descriptors are compared with a :math:`L^1`-distance. +For a given descriptor, if the ratio between the closest-neighbor the +second-closest-neighbor is below this threshold, then a matching is added to the list. +Increasing this value leads to a larger number of matchings, certainly less accurate. + + +Region of Interest for image alignment +...................................... + +When processing the image matching, a region of interest (ROI) can be specified +on the image. +It is a binary image which can have any shape. +For instance, if a sample is centered on the image, the user can select the +center of the image before processing. + + +.. figure:: img/sift_frame_ROI.jpg + :align: center + :alt: Sample with region of interest + +It both accelerates the processing and avoids to do match keypoints that are not +on the sample. + + + +References +.......... + +- David G. Lowe, Distinctive image features from scale-invariant keypoints, International Journal of Computer Vision, vol. 60, no 2, 2004, p. 91–110 - "http://www.cs.ubc.ca/~lowe/papers/ijcv04.pdf" + + diff --git a/doc/source/img/silx.ico b/doc/source/img/silx.ico new file mode 100644 index 0000000..9db7313 Binary files /dev/null and b/doc/source/img/silx.ico differ diff --git a/doc/source/img/silx_large.png b/doc/source/img/silx_large.png new file mode 100644 index 0000000..56fcfd3 Binary files /dev/null and b/doc/source/img/silx_large.png differ diff --git a/doc/source/img/silx_small.png b/doc/source/img/silx_small.png new file mode 100755 index 0000000..32aba21 Binary files /dev/null and b/doc/source/img/silx_small.png differ diff --git a/doc/source/index.rst b/doc/source/index.rst new file mode 100644 index 0000000..656f774 --- /dev/null +++ b/doc/source/index.rst @@ -0,0 +1,47 @@ +silx |version| +============== + +The silx project aims at providing a collection of Python packages to support the development of data assessment, reduction and analysis applications at synchrotron radiation facilities. +It aims at providing reading/writing different file formats, data reduction routines and a set of Qt widgets to browse and visualize data. + +The current version provides reading `SPEC `_ file format, histogramming, fitting, curves and image plot widget with a set of associated tools. + +.. toctree:: + :hidden: + + overview.rst + install.rst + description/index.rst + tutorials.rst + modules/index.rst + changelog.rst + license.rst + virtualenv.rst + +:doc:`overview` + Releases, repository, issue tracker, mailing list, ... + +:doc:`install` + How to install *silx* on Linux, Windows and MacOS X + +:doc:`description/index` + Description of the different algorithms and their implementation + +:doc:`tutorials` + Tutorials and sample code + +:doc:`modules/index` + Documentation of the packages included in *silx* + +:doc:`changelog` + List of changes between releases + +:doc:`license` + License and copyright information + +Indices +======= + +* :ref:`modindex` +* :ref:`search` +* :ref:`genindex` diff --git a/doc/source/install.rst b/doc/source/install.rst new file mode 100644 index 0000000..1bf5b9d --- /dev/null +++ b/doc/source/install.rst @@ -0,0 +1,306 @@ + +Installation steps +================== + +*silx* supports `Python `_ versions 2.7, 3.4 and 3.5. + +To install *silx* on Windows, read the `Windows instructions`_. + +To install *silx* on Linux, read the `Linux instructions`_. + +To install *silx* on MacOS, read the `MacOS instructions`_. + +You will find the simple instructions for each platform at the beginning of each section, followed by more detailed instructions concerning dependencies and alternative installation methods. + +For all platform, to install *silx* from the source, see `Installing from source`_. + +To install *silx* in a virtualenv, read :ref:`silx-venv`. + +Dependencies +------------ + +The only mandatory dependency of *silx* is `numpy `_. + +Yet, a set of `Optional dependencies`_ is necessary to enable all *silx* features. + +Optional dependencies ++++++++++++++++++++++ + +The GUI widgets depend on the following extra packages: + +* A Qt binding: either `PyQt5, PyQt4 `_ or `PySide `_ +* `matplotlib `_ +* `PyOpenGL `_ +* `IPython `_ and `qt_console `_ for the ``silx.gui.console`` widget. + +Tools for reading and writing files depend on the following packages: + +* `h5py `_ for HDF5 files +* `fabio `_ for multiple image formats + +*silx.opencl* and *silx.image.sift* further depends on OpenCL and the following packages to : + +* `pyopencl `_ +* `Mako `_ + +Build dependencies +++++++++++++++++++ + +In addition to run-time dependencies, building *silx* requires a C/C++ compiler, `numpy `_ and `cython `_ (optional). + +On Windows it is recommended to use Python 3.5, because with previous versions of Python, it might be difficult to compile the extensions. + +This project uses cython to generate C files. +Cython is not mandatory to build *silx* and is only needed when developing binary modules. +If using cython, *silx* requires at least version 0.18 (with memory-view support). + + +Linux instructions +------------------ + +If NumPy is not installed on your system, you need to install it first +either with the package manager of your system (recommended way) or with pip:: + + pip install numpy --user + +On Linux, you can install *silx* in your home directory:: + + pip install silx --user + +.. note:: + + Replace the ``pip`` command with ``pip3`` to install *silx* or any other library for Python 3. + +.. note:: + + This installs *silx* without the optional dependencies. + +To install *silx* on Debian 8, see `Installing a Debian package`_. +This method requires **sudo** privileges, but has the benefit of installing dependencies in a simple way. + +CentOS 7 rpm packages are provided by Max IV at the following url: http://pubrepo.maxiv.lu.se/rpm/el7/x86_64/ + +Fedora 23 rpm packages are provided by Max IV at http://pubrepo.maxiv.lu.se/rpm/fc23/x86_64/ + +An Arch Linux (AUR) package is also available: https://aur.archlinux.org/packages/python-silx + +You can also choose to compile and install *silx* from it's sources: +see `Installing from source`_. + + + +Installing a Debian package ++++++++++++++++++++++++++++ + +Debian 8 (Jessie) packages are available on http://www.silx.org/pub/debian/ for amd64 computers. +To install it, you need to download this file:: + + http://www.silx.org/pub/debian/silx.list + +and copy it into the /etc/apt/source.list.d folder. +Then run ``apt-get update`` and ``apt-get install python-silx`` + +:: + + wget http://www.silx.org/pub/debian/silx.list + sudo cp silx.list /etc/apt/sources.list.d + sudo apt-get update + sudo apt-get install python-silx python3-silx + +.. note:: + + The packages are built automatically, hence not signed. + You have to accept the installation of non-signed packages. + +If the packages are not installed, it might be due to the priority list. +You can display the priority list using `apt-cache policy python-silx`. +If the Pin-number of silx.org is too low compared to other sources: +download http://www.silx.org/pub/debian/silx.pref into /etc/apt/preferences.d +and start the update/install procedure again. + + +Windows instructions +-------------------- + +The simple way of installing the *silx* library on Windows is to type following +commands in a command prompt:: + + pip install silx + +.. note:: + + This installs *silx* without the optional dependencies. + Instructions on how to install dependencies are given in the + `Installing dependencies`_ section. + +This assumes you have Python and pip installed and configured. If you don't, +read the following sections. + + +Installing Python ++++++++++++++++++ + +Download and install Python from `python.org `_. + +We recommend that you install the 64bits version of Python, which is not the default version suggested on the Python website. The 32bits version is limited to 2 GB of memory, and also we don't provide a silx wheel for it. This means that you would have to install silx from its sources, which requires you to install a C compiler first. + +We also encourage you to use Python 3.5 or newer. + +Configure Python as explained on `docs.python.org +`_ to add +the python installation directory to your PATH environment variable. + +Alternative Scientific Python stacks exists, such as `WinPython `_. +They all offer most of the scientific packages already installed which makes the installation of dependencies much easier. + +Installing pip +++++++++++++++ + +Recent version of Python (`> 2.7.9` or `> 3.4`) provide pip by default. + +If you have an older version of Python and you do not wish to upgrade it, +you can install pip yourself. + +Download the script https://bootstrap.pypa.io/get-pip.py and execute it in a +command prompt:: + + python get-pip.py + + +Using pip ++++++++++ + +Configure your PATH environment variable to include the pip installation +directory, the same way as described for Python. + +The pip installation directory will likely be ``C:\Python35\Scripts\``. + +Then you will be able to use all pip commands listed in following in a command +prompt. + + +Installing dependencies ++++++++++++++++++++++++ + +Some of the dependencies may be simply installed with pip:: + + pip install numpy + pip install matplotlib + pip install PyOpenGL + pip install PyQt5 + pip install PySide + +Regarding the `h5py` and `PyQt4` modules, you can find the wheels at +Christoph Gohlke's repository: + +http://www.lfd.uci.edu/~gohlke/pythonlibs/ + +Download the appropriate `.whl` file for your system and install them with pip:: + + pip install h5py*.whl + pip install PyQt4*.whl + +`PyQt5` can be downloaded as a binary package for `Python 3.5` on the +`Riverbank Computing website `_. +This package contains everything needed for `PyQt5`, including `Qt`. + + +Installing *silx* ++++++++++++++++++ + +Provided numpy is installed, you can install *silx* with:: + + pip install silx + + +MacOS instructions +------------------ + +The easy way to install *silx* on MacOS, is:: + + pip install silx + +This should work without issues, as binary wheels of *silx* are provided on +PyPi. + +Wheels are available for *h5py* on MacOS, so you can install it with:: + + pip install h5py + +If at the time of your installation a new version of *h5py* has been released but +the corresponding MacOS wheel is not ready, you should install the latest version including +a wheel: ``pip install h5py==2.6.0`` + +A PyQt5 wheel is now available for Python 3.5 on MacOS: https://pypi.python.org/simple/pyqt5/. +Download it and install it with:: + + pip install PyQt5-5.6-cp35-cp35m-macosx_10_6_intel.whl + +This should work for all versions of MacOS from 10.6. + + +Installing from source +---------------------- + +Building *silx* from the source requires some `Build dependencies`_. + +Building from source +++++++++++++++++++++ + +Source package of *silx* releases can be downloaded from `the pypi project page `_. + +After downloading the `silx-x.y.z.tar.gz` archive, extract its content:: + + tar xzvf silx-x.y.z.tar.gz + +Alternatively, you can get the latest source code from the master branch of the `git repository `_: https://github.com/silx-kit/silx/archive/master.zip + +You can now build and install *silx* from its sources:: + + cd silx-x.y.z + pip uninstall -y silx + pip install . [--user] + +Known issues +............ + +There are specific issues related to MacOSX. If you get this error:: + + UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 1335: ordinal not in range(128) + +This is related to the two environment variable LC_ALL and LANG not defined (or wrongly defined to UTF-8). +To set the environment variable, type on the command line:: + + export LC_ALL=en_US.UTF-8 + export LANG=en_US.UTF-8 + +Advanced build options +++++++++++++++++++++++ + +In case you want more control over the build procedure, the build command is:: + + python setup.py build + +After this build, you will still need to install *silx* to be able to use it:: + + python setup.py install [--user] + +There are few advanced options to ``setup.py build``: + +* ``--no-cython``: Prevent Cython (even if installed) to re-generate the C source code. + Use the one provided by the development team. +* ``--no-openmp``: Recompiles the Cython code without OpenMP support (default for MacOSX). +* ``--openmp``: Recompiles the Cython code with OpenMP support (default for Windows and Linux). + +To build the documentation (this requires `Sphinx `_), run:: + + python setup.py build build_doc + + +Testing ++++++++ + +To run the tests of an installed version of *silx*, from the python interpreter, run: + +>>> import silx.test +>>> silx.test.run_tests() diff --git a/doc/source/license.rst b/doc/source/license.rst new file mode 100644 index 0000000..6b38b8e --- /dev/null +++ b/doc/source/license.rst @@ -0,0 +1,10 @@ +License +======= + +The source code of *silx* is mostly licensed under the `MIT `_ and `LGPL 2.1 `_ licenses. + +The following list provides the copyright and license of the different source files of the project: + +.. include:: ../../copyright + :literal: + :start-after: silx-kit/silx diff --git a/doc/source/modules/gui/console.rst b/doc/source/modules/gui/console.rst new file mode 100644 index 0000000..5c8398e --- /dev/null +++ b/doc/source/modules/gui/console.rst @@ -0,0 +1,9 @@ + +.. currentmodule:: silx.gui + +:mod:`console`: IPython console widgets +--------------------------------------- + +.. automodule:: silx.gui.console + :members: + :exclude-members: main, sizeHint diff --git a/doc/source/modules/gui/data/arraytable.rst b/doc/source/modules/gui/data/arraytable.rst new file mode 100644 index 0000000..b929cd5 --- /dev/null +++ b/doc/source/modules/gui/data/arraytable.rst @@ -0,0 +1,23 @@ + +.. currentmodule:: silx.gui.data + +:mod:`ArrayTableWidget`: Browsing Numpy arrays +---------------------------------------------- + +.. automodule:: silx.gui.data.ArrayTableWidget + +Widget +++++++ + +.. autoclass:: silx.gui.data.ArrayTableWidget.ArrayTableWidget + :members: + + + +Data model +++++++++++ + +.. automodule:: silx.gui.data.ArrayTableModel + +.. autoclass:: silx.gui.data.ArrayTableModel.ArrayTableModel + :exclude-members: data, rowCount, columnCount, headerData, flags, setData, diff --git a/doc/source/modules/gui/data/dataviewer.rst b/doc/source/modules/gui/data/dataviewer.rst new file mode 100644 index 0000000..7f87c49 --- /dev/null +++ b/doc/source/modules/gui/data/dataviewer.rst @@ -0,0 +1,7 @@ +:mod:`DataViewer`: Widget to display any kind of data +----------------------------------------------------- + +.. automodule:: silx.gui.data.DataViewer + +.. autoclass:: DataViewer + :members: diff --git a/doc/source/modules/gui/data/dataviewerframe.rst b/doc/source/modules/gui/data/dataviewerframe.rst new file mode 100644 index 0000000..12ccfa0 --- /dev/null +++ b/doc/source/modules/gui/data/dataviewerframe.rst @@ -0,0 +1,7 @@ +:mod:`DataViewerFrame`: Widget to display any kind of data +---------------------------------------------------------- + +.. automodule:: silx.gui.data.DataViewerFrame + +.. autoclass:: DataViewerFrame + :members: diff --git a/doc/source/modules/gui/data/img/DataViewer.png b/doc/source/modules/gui/data/img/DataViewer.png new file mode 100644 index 0000000..719c822 Binary files /dev/null and b/doc/source/modules/gui/data/img/DataViewer.png differ diff --git a/doc/source/modules/gui/data/img/DataViewerFrame.png b/doc/source/modules/gui/data/img/DataViewerFrame.png new file mode 100644 index 0000000..88dc09a Binary files /dev/null and b/doc/source/modules/gui/data/img/DataViewerFrame.png differ diff --git a/doc/source/modules/gui/data/img/NumpyAxesSelector.png b/doc/source/modules/gui/data/img/NumpyAxesSelector.png new file mode 100644 index 0000000..c508b80 Binary files /dev/null and b/doc/source/modules/gui/data/img/NumpyAxesSelector.png differ diff --git a/doc/source/modules/gui/data/index.rst b/doc/source/modules/gui/data/index.rst new file mode 100644 index 0000000..e70138d --- /dev/null +++ b/doc/source/modules/gui/data/index.rst @@ -0,0 +1,19 @@ + +.. currentmodule:: silx.gui + +:mod:`data`: Widgets for data visualization +------------------------------------------- + +.. automodule:: silx.gui.data + + +Public modules: + +.. toctree:: + :maxdepth: 2 + + arraytable.rst + dataviewerframe.rst + dataviewer.rst + numpyaxesselector.rst + textformatter.rst diff --git a/doc/source/modules/gui/data/numpyaxesselector.rst b/doc/source/modules/gui/data/numpyaxesselector.rst new file mode 100644 index 0000000..e1ab952 --- /dev/null +++ b/doc/source/modules/gui/data/numpyaxesselector.rst @@ -0,0 +1,7 @@ +:mod:`NumpyAxesSelector`:Widget to select a view from a numpy array +------------------------------------------------------------------- + +.. automodule:: silx.gui.data.NumpyAxesSelector + +.. autoclass:: NumpyAxesSelector + :members: diff --git a/doc/source/modules/gui/data/textformatter.rst b/doc/source/modules/gui/data/textformatter.rst new file mode 100644 index 0000000..6903f80 --- /dev/null +++ b/doc/source/modules/gui/data/textformatter.rst @@ -0,0 +1,7 @@ +:mod:`TextFormatter`: Common text formatter +------------------------------------------- + +.. automodule:: silx.gui.data.TextFormatter + +.. autoclass:: TextFormatter + :members: diff --git a/doc/source/modules/gui/designer.rst b/doc/source/modules/gui/designer.rst new file mode 100644 index 0000000..fc52e1f --- /dev/null +++ b/doc/source/modules/gui/designer.rst @@ -0,0 +1 @@ +.. include:: ../../../../qtdesigner_plugins/README.rst diff --git a/doc/source/modules/gui/fit/backgroundwidget.rst b/doc/source/modules/gui/fit/backgroundwidget.rst new file mode 100644 index 0000000..eea2052 --- /dev/null +++ b/doc/source/modules/gui/fit/backgroundwidget.rst @@ -0,0 +1,27 @@ + +.. currentmodule:: silx.gui.fit + +:mod:`BackgroundWidget` +======================= + +.. automodule:: silx.gui.fit.BackgroundWidget + + +.. |imgBGWidget| image:: ./img/bgwidget.png + :height: 300px + :align: middle + +|imgBGWidget| + + +API +--- + +.. currentmodule:: silx.gui.fit.BackgroundWidget + +.. autoclass:: BackgroundWidget + :members: + +.. autoclass:: BackgroundDialog + :members: + diff --git a/doc/source/modules/gui/fit/fitwidget.rst b/doc/source/modules/gui/fit/fitwidget.rst new file mode 100644 index 0000000..5eb0280 --- /dev/null +++ b/doc/source/modules/gui/fit/fitwidget.rst @@ -0,0 +1,18 @@ + +.. currentmodule:: silx.gui.fit + +:mod:`FitWidget` +================ + +.. automodule:: silx.gui.fit.FitWidget + +For a tutorial on how to use :class:`FitWidget`, see :ref:`fitwidget-tutorial`. + +API +--- + +.. currentmodule:: silx.gui.fit.FitWidget + +.. autoclass:: FitWidget + :members: __init__, configdialogs, setData, associateConfigDialog + diff --git a/doc/source/modules/gui/fit/img/bgwidget.png b/doc/source/modules/gui/fit/img/bgwidget.png new file mode 100644 index 0000000..724eadb Binary files /dev/null and b/doc/source/modules/gui/fit/img/bgwidget.png differ diff --git a/doc/source/modules/gui/fit/index.rst b/doc/source/modules/gui/fit/index.rst new file mode 100644 index 0000000..67c22a1 --- /dev/null +++ b/doc/source/modules/gui/fit/index.rst @@ -0,0 +1,32 @@ + +.. currentmodule:: silx.gui + +:mod:`fit`: Fit widgets +------------------------ + +.. automodule:: silx.gui.fit + +Snapshot of the widgets: + + +.. |imgFitWidget| image:: ../../../Tutorials/img/fitwidget4.png + :height: 150px + :align: middle + +.. |imgBGWidget| image:: ./img/bgwidget.png + :height: 150px + :align: middle + +=================== ========================== +|imgFitWidget| |imgBGWidget| +:class:`FitWidget` :class:`BackgroundWidget` +=================== ========================== + +Public modules: + +.. toctree:: + :maxdepth: 2 + + fitwidget.rst + backgroundwidget.rst + diff --git a/doc/source/modules/gui/hdf5/examples_hdf5widget.rst b/doc/source/modules/gui/hdf5/examples_hdf5widget.rst new file mode 100644 index 0000000..90f218f --- /dev/null +++ b/doc/source/modules/gui/hdf5/examples_hdf5widget.rst @@ -0,0 +1,6 @@ +hdf5widget.py +============= + +Sample code demonstrating :mod:`silx.gui.hdf5` widgets: + +.. literalinclude:: ../../../../../examples/hdf5widget.py diff --git a/doc/source/modules/gui/hdf5/getting_started.rst b/doc/source/modules/gui/hdf5/getting_started.rst new file mode 100644 index 0000000..e843cac --- /dev/null +++ b/doc/source/modules/gui/hdf5/getting_started.rst @@ -0,0 +1,226 @@ +.. currentmodule:: silx.gui.hdf5 + +Getting started with HDF5 widgets +================================= + +Silx provides an implementation of a tree model and a tree view for HDF5 files. +The aim of this tree is to provide a convenient read-only widget for a big +amount of data and supporting file formats often used in synchrotrons. + +This page provides some source code to show how to use this widget. + +Commented source code +--------------------- + +Import and create your tree view +++++++++++++++++++++++++++++++++ + +HDF5 widgets are all exposed by the package `silx.gui.hdf5`. + +.. testsetup:: * + + from silx.gui import qt + app = qt.QApplication([]) + import silx.gui.hdf5 + treeview = silx.gui.hdf5.Hdf5TreeView() + header = treeview.header() + model = treeview.findHdf5TreeModel() + +.. testcode:: + + import silx.gui.hdf5 + treeview = silx.gui.hdf5.Hdf5TreeView() + +Custom your tree view ++++++++++++++++++++++ + +The tree view can be customized to be sorted by default. + +.. testcode:: + + # Sort content of files by time or name + treeview.setSortingEnabled(True) + +The model can be customized to support mouse interaction. +A convenient method :meth:`Hdf5TreeView.findHdf5TreeModel` returns the main +HDF5 model used through proxy models. + +.. testcode:: + + model = treeview.findHdf5TreeModel() + + # Avoid the user to drop file in the widget + model.setFileDropEnabled(False) + + # Allow the user to reorder files with drag-and-drop + model.setFileMoveEnabled(True) + +The tree view is also provided with a custom header which help to choose +visible columns. + +.. testcode:: + + header = treeview.header() + + # Select displayed columns + column_ids = [treeview.findHdf5TreeModel().NAME_COLUMN] + header.setSections(column_ids) + + # Do not allow the user to custom visible columns + header.setEnableHideColumnsPopup(False) + +Add a file by name +++++++++++++++++++ + +The model can be used to add HDF5. It is internally using +:func:`silx.io.open`. + +.. code-block:: python + + model.insertFile("test.h5") + +Add a file with h5py +++++++++++++++++++++ + +The model internally uses :mod:`h5py` object API. We can use h5py file, group +and dataset as it is. + +.. code-block:: python + + import h5py + h5 = h5py.File("test.h5") + + # We can use file + model.insertH5pyObject(h5) + + # or group or dataset + model.insertH5pyObject(h5["group1"]) + model.insertH5pyObject(h5["group1/dataset50"]) + +Add a file with silx +++++++++++++++++++++ + +Silx also provides an input API. It supports HDF5 files through :mod:`h5py`. + +.. code-block:: python + + import silx.io + + # We can load HDF5 files + model.insertH5pyObject(silx.io.open("test.h5")) + + # or Spec files + model.insertH5pyObject(silx.io.open("test.dat")) + + +Custom context menu ++++++++++++++++++++ + +The :class:`Hdf5TreeView` provides a callback API to populate the context menu. +The callback receives a :class:`Hdf5ContextMenuEvent` every time the user +requests the context menu. The event contains :class:`H5Node` objects which wrap +h5py objects with extra information. + +.. testcode:: + + def my_action_callback(obj): + # do what you want + pass + + def my_callback(event): + objects = list(event.source().selectedH5Nodes()) + obj = objects[0] # for single selection + + menu = event.menu() + if obj.ntype is h5py.Dataset: + action = qt.QAction("My funky action on datasets only", menu) + action.triggered.connect(lambda: my_action_callback(obj)) + menu.addAction(action) + + treeview.addContextMenuCallback(my_callback) + +Capture selection ++++++++++++++++++ + +The :class:`Hdf5TreeView` widget provides default Qt signals inherited from +`QAbstractItemView`. + +- `activated`: + This signal is emitted when the item specified by index is + activated by the user. How to activate items depends on the platform; + e.g., by single- or double-clicking the item, or by pressing the + Return or Enter key when the item is current. +- `clicked`: + This signal is emitted when a mouse button is clicked. The item the mouse + was clicked on is specified by index. The signal is only emitted when the + index is valid. +- `doubleClicked`: + This signal is emitted when a mouse button is double-clicked. The item + the mouse was double-clicked on is specified by index. The signal is + only emitted when the index is valid. +- `entered`: + This signal is emitted when the mouse cursor enters the item specified by + index. Mouse tracking needs to be enabled for this feature to work. +- `pressed`: + This signal is emitted when a mouse button is pressed. The item the mouse + was pressed on is specified by index. The signal is only emitted when the + index is valid. + +The method :meth:`Hdf5TreeView.selectedH5Nodes` returns an iterator of :class:`H5Node` +objects which wrap h5py objects with extra information. + +.. testcode:: + + def my_callback(index): + objects = list(treeview.selectedH5Nodes()) + obj = objects[0] # for single selection + + print(obj) + + print(obj.basename) # not provided by h5py + print(obj.name) + print(obj.file.filename) + + print(obj.local_basename) # not provided by h5py + print(obj.local_name) # not provided by h5py + print(obj.local_file.filename) # not provided by h5py + + print(obj.attrs) + + if obj.ntype is h5py.Dataset: + print(obj.dtype) + print(obj.shape) + print(obj.value) # create a copy of data of the dataset + print(obj.h5py_object) # reference to the Hdf5 dataset (or group) + + treeview.clicked.connect(my_callback) + +Example +------- + +.. toctree:: + :hidden: + + examples_hdf5widget.rst + +The :doc:`examples_hdf5widget` sample code provides an example of properties of +the view, the model and the header. + +.. image:: img/Hdf5Example.png + :height: 200px + :width: 400px + :alt: Example for HDF5TreeView features + :align: center + +Source code: :doc:`examples_hdf5widget`. + +After installing `silx` and downloading the script, you can start it from the +command prompt: + +.. code-block:: bash + + python hdf5widget.py + +This example loads files added to the command line, or files dropped from the +file system. It also provides a GUI to display test files created +programmatically. diff --git a/doc/source/modules/gui/hdf5/h5node.rst b/doc/source/modules/gui/hdf5/h5node.rst new file mode 100644 index 0000000..a57bbe7 --- /dev/null +++ b/doc/source/modules/gui/hdf5/h5node.rst @@ -0,0 +1,9 @@ + +.. currentmodule:: silx.gui.hdf5 + +:class:`H5Node` class +--------------------- + +.. autoclass:: H5Node + :show-inheritance: + :members: diff --git a/doc/source/modules/gui/hdf5/hdf5contextmenuevent.rst b/doc/source/modules/gui/hdf5/hdf5contextmenuevent.rst new file mode 100644 index 0000000..972a267 --- /dev/null +++ b/doc/source/modules/gui/hdf5/hdf5contextmenuevent.rst @@ -0,0 +1,9 @@ + +.. currentmodule:: silx.gui.hdf5 + +:class:`Hdf5ContextMenuEvent` class +----------------------------------- + +.. autoclass:: Hdf5ContextMenuEvent + :show-inheritance: + :members: diff --git a/doc/source/modules/gui/hdf5/hdf5treemodel.rst b/doc/source/modules/gui/hdf5/hdf5treemodel.rst new file mode 100644 index 0000000..1269e7d --- /dev/null +++ b/doc/source/modules/gui/hdf5/hdf5treemodel.rst @@ -0,0 +1,9 @@ + +.. currentmodule:: silx.gui.hdf5 + +:class:`Hdf5TreeModel` class +---------------------------- + +.. autoclass:: Hdf5TreeModel + :show-inheritance: + :members: diff --git a/doc/source/modules/gui/hdf5/hdf5treeview.rst b/doc/source/modules/gui/hdf5/hdf5treeview.rst new file mode 100644 index 0000000..cd44f74 --- /dev/null +++ b/doc/source/modules/gui/hdf5/hdf5treeview.rst @@ -0,0 +1,9 @@ + +.. currentmodule:: silx.gui.hdf5 + +:class:`Hdf5TreeView` class +--------------------------- + +.. autoclass:: Hdf5TreeView + :show-inheritance: + :members: diff --git a/doc/source/modules/gui/hdf5/img/Hdf5Example.png b/doc/source/modules/gui/hdf5/img/Hdf5Example.png new file mode 100644 index 0000000..2b1ed0b Binary files /dev/null and b/doc/source/modules/gui/hdf5/img/Hdf5Example.png differ diff --git a/doc/source/modules/gui/hdf5/img/Hdf5TreeView.png b/doc/source/modules/gui/hdf5/img/Hdf5TreeView.png new file mode 100644 index 0000000..2010069 Binary files /dev/null and b/doc/source/modules/gui/hdf5/img/Hdf5TreeView.png differ diff --git a/doc/source/modules/gui/hdf5/index.rst b/doc/source/modules/gui/hdf5/index.rst new file mode 100644 index 0000000..cd2c4eb --- /dev/null +++ b/doc/source/modules/gui/hdf5/index.rst @@ -0,0 +1,46 @@ + +.. currentmodule:: silx.gui + +:mod:`hdf5`: HDF5 widgets +========================= + +.. toctree:: + :hidden: + + getting_started.rst + +.. currentmodule:: silx.gui.hdf5 + +.. automodule:: silx.gui.hdf5 + +For an introduction to the widgets of this package, see :doc:`getting_started`. + +Widgets gallery +--------------- + +.. |imgHdf5TreeView| image:: img/Hdf5TreeView.png + :height: 150px + :align: middle + +.. list-table:: + :widths: 1 4 + :header-rows: 1 + + * - Widget + - Description + * - |imgHdf5TreeView| + - :class:`Hdf5TreeView` is the base Qt widget providing a tree view of + multiple HDF5 files, or assimilated file with an adapter. + + +Public modules +-------------- + +.. toctree:: + :maxdepth: 2 + + hdf5treeview.rst + hdf5treemodel.rst + hdf5contextmenuevent.rst + h5node.rst + nexussortfilterproxymodel.rst diff --git a/doc/source/modules/gui/hdf5/nexussortfilterproxymodel.rst b/doc/source/modules/gui/hdf5/nexussortfilterproxymodel.rst new file mode 100644 index 0000000..ec2a8a9 --- /dev/null +++ b/doc/source/modules/gui/hdf5/nexussortfilterproxymodel.rst @@ -0,0 +1,9 @@ + +.. currentmodule:: silx.gui.hdf5 + +:class:`NexusSortFilterProxyModel` class +---------------------------------------- + +.. autoclass:: NexusSortFilterProxyModel + :show-inheritance: + :members: diff --git a/doc/source/modules/gui/icons.rst b/doc/source/modules/gui/icons.rst new file mode 100644 index 0000000..61ea71d --- /dev/null +++ b/doc/source/modules/gui/icons.rst @@ -0,0 +1,346 @@ + +.. AUTOMATICALLY GENERATED FILE DO NOT EDIT + Use update_icons_rst.py script instead + +.. currentmodule:: silx.gui + +:mod:`icons`: Set of icons +-------------------------- + +.. automodule:: silx.gui.icons + :members: + +Available icons ++++++++++++++++ + +.. list-table:: + :widths: 1 4 + :header-rows: 1 + + * - Icon + - Name + * - |3d-plane-normal-x| + - 3d-plane-normal-x + * - |3d-plane-normal-y| + - 3d-plane-normal-y + * - |3d-plane-normal-z| + - 3d-plane-normal-z + * - |3d-plane| + - 3d-plane + * - |arrow-keys| + - arrow-keys + * - |camera| + - camera + * - |clipboard| + - clipboard + * - |close| + - close + * - |colormap| + - colormap + * - |crop| + - crop + * - |crosshair| + - crosshair + * - |cube-back| + - cube-back + * - |cube-bottom| + - cube-bottom + * - |cube-front| + - cube-front + * - |cube-left| + - cube-left + * - |cube-right| + - cube-right + * - |cube-top| + - cube-top + * - |cube| + - cube + * - |document-open| + - document-open + * - |document-print| + - document-print + * - |document-save| + - document-save + * - |draw-brush| + - draw-brush + * - |draw-pencil| + - draw-pencil + * - |draw-rubber| + - draw-rubber + * - |edit-copy| + - edit-copy + * - |first| + - first + * - |folder| + - folder + * - |image-mask| + - image-mask + * - |image-select-add| + - image-select-add + * - |image-select-box| + - image-select-box + * - |image-select-brush| + - image-select-brush + * - |image-select-erase-rubber| + - image-select-erase-rubber + * - |image-select-erase| + - image-select-erase + * - |image| + - image + * - |item-0dim| + - item-0dim + * - |item-1dim| + - item-1dim + * - |item-2dim| + - item-2dim + * - |item-3dim| + - item-3dim + * - |item-ndim| + - item-ndim + * - |item-object| + - item-object + * - |last| + - last + * - |math-average| + - math-average + * - |math-derive| + - math-derive + * - |math-energy| + - math-energy + * - |math-fit| + - math-fit + * - |math-normalize| + - math-normalize + * - |math-peak-reset| + - math-peak-reset + * - |math-peak-search| + - math-peak-search + * - |math-peak| + - math-peak + * - |math-sigma| + - math-sigma + * - |math-smooth| + - math-smooth + * - |math-substract| + - math-substract + * - |math-swap-sign| + - math-swap-sign + * - |math-ymin-to-zero| + - math-ymin-to-zero + * - |next| + - next + * - |normal| + - normal + * - |pixel-intensities| + - pixel-intensities + * - |plot-grid| + - plot-grid + * - |plot-roi-above| + - plot-roi-above + * - |plot-roi-below| + - plot-roi-below + * - |plot-roi-between| + - plot-roi-between + * - |plot-roi-reset| + - plot-roi-reset + * - |plot-roi| + - plot-roi + * - |plot-toggle-points| + - plot-toggle-points + * - |plot-widget| + - plot-widget + * - |plot-window-image| + - plot-window-image + * - |plot-window| + - plot-window + * - |plot-xauto| + - plot-xauto + * - |plot-xlog| + - plot-xlog + * - |plot-yauto| + - plot-yauto + * - |plot-ydown| + - plot-ydown + * - |plot-ylog| + - plot-ylog + * - |plot-yup| + - plot-yup + * - |previous| + - previous + * - |profile1D| + - profile1D + * - |profile2D| + - profile2D + * - |remove| + - remove + * - |rudder| + - rudder + * - |selected| + - selected + * - |shape-circle-solid| + - shape-circle-solid + * - |shape-circle| + - shape-circle + * - |shape-diagonal| + - shape-diagonal + * - |shape-ellipse-solid| + - shape-ellipse-solid + * - |shape-ellipse| + - shape-ellipse + * - |shape-horizontal| + - shape-horizontal + * - |shape-polygon| + - shape-polygon + * - |shape-rectangle| + - shape-rectangle + * - |shape-square| + - shape-square + * - |shape-vertical| + - shape-vertical + * - |silx| + - silx + * - |sliders-off| + - sliders-off + * - |sliders-on| + - sliders-on + * - |spec| + - spec + * - |test-png| + - test-png + * - |view-1d| + - view-1d + * - |view-2d-stack| + - view-2d-stack + * - |view-2d| + - view-2d + * - |view-3d| + - view-3d + * - |view-fullscreen| + - view-fullscreen + * - |view-nofullscreen| + - view-nofullscreen + * - |view-raw| + - view-raw + * - |view-refresh| + - view-refresh + * - |view-text| + - view-text + * - |window-new| + - window-new + * - |zoom-in| + - zoom-in + * - |zoom-original| + - zoom-original + * - |zoom-out| + - zoom-out + * - |zoom| + - zoom + +.. |3d-plane-normal-x| image:: ../../../../silx/resources/gui/icons/3d-plane-normal-x.png +.. |3d-plane-normal-y| image:: ../../../../silx/resources/gui/icons/3d-plane-normal-y.png +.. |3d-plane-normal-z| image:: ../../../../silx/resources/gui/icons/3d-plane-normal-z.png +.. |3d-plane| image:: ../../../../silx/resources/gui/icons/3d-plane.png +.. |arrow-keys| image:: ../../../../silx/resources/gui/icons/arrow-keys.png +.. |camera| image:: ../../../../silx/resources/gui/icons/camera.png +.. |clipboard| image:: ../../../../silx/resources/gui/icons/clipboard.png +.. |close| image:: ../../../../silx/resources/gui/icons/close.png +.. |colormap| image:: ../../../../silx/resources/gui/icons/colormap.png +.. |crop| image:: ../../../../silx/resources/gui/icons/crop.png +.. |crosshair| image:: ../../../../silx/resources/gui/icons/crosshair.png +.. |cube-back| image:: ../../../../silx/resources/gui/icons/cube-back.png +.. |cube-bottom| image:: ../../../../silx/resources/gui/icons/cube-bottom.png +.. |cube-front| image:: ../../../../silx/resources/gui/icons/cube-front.png +.. |cube-left| image:: ../../../../silx/resources/gui/icons/cube-left.png +.. |cube-right| image:: ../../../../silx/resources/gui/icons/cube-right.png +.. |cube-top| image:: ../../../../silx/resources/gui/icons/cube-top.png +.. |cube| image:: ../../../../silx/resources/gui/icons/cube.png +.. |document-open| image:: ../../../../silx/resources/gui/icons/document-open.png +.. |document-print| image:: ../../../../silx/resources/gui/icons/document-print.png +.. |document-save| image:: ../../../../silx/resources/gui/icons/document-save.png +.. |draw-brush| image:: ../../../../silx/resources/gui/icons/draw-brush.png +.. |draw-pencil| image:: ../../../../silx/resources/gui/icons/draw-pencil.png +.. |draw-rubber| image:: ../../../../silx/resources/gui/icons/draw-rubber.png +.. |edit-copy| image:: ../../../../silx/resources/gui/icons/edit-copy.png +.. |first| image:: ../../../../silx/resources/gui/icons/first.png +.. |folder| image:: ../../../../silx/resources/gui/icons/folder.png +.. |image-mask| image:: ../../../../silx/resources/gui/icons/image-mask.png +.. |image-select-add| image:: ../../../../silx/resources/gui/icons/image-select-add.png +.. |image-select-box| image:: ../../../../silx/resources/gui/icons/image-select-box.png +.. |image-select-brush| image:: ../../../../silx/resources/gui/icons/image-select-brush.png +.. |image-select-erase-rubber| image:: ../../../../silx/resources/gui/icons/image-select-erase-rubber.png +.. |image-select-erase| image:: ../../../../silx/resources/gui/icons/image-select-erase.png +.. |image| image:: ../../../../silx/resources/gui/icons/image.png +.. |item-0dim| image:: ../../../../silx/resources/gui/icons/item-0dim.png +.. |item-1dim| image:: ../../../../silx/resources/gui/icons/item-1dim.png +.. |item-2dim| image:: ../../../../silx/resources/gui/icons/item-2dim.png +.. |item-3dim| image:: ../../../../silx/resources/gui/icons/item-3dim.png +.. |item-ndim| image:: ../../../../silx/resources/gui/icons/item-ndim.png +.. |item-object| image:: ../../../../silx/resources/gui/icons/item-object.png +.. |last| image:: ../../../../silx/resources/gui/icons/last.png +.. |math-average| image:: ../../../../silx/resources/gui/icons/math-average.png +.. |math-derive| image:: ../../../../silx/resources/gui/icons/math-derive.png +.. |math-energy| image:: ../../../../silx/resources/gui/icons/math-energy.png +.. |math-fit| image:: ../../../../silx/resources/gui/icons/math-fit.png +.. |math-normalize| image:: ../../../../silx/resources/gui/icons/math-normalize.png +.. |math-peak-reset| image:: ../../../../silx/resources/gui/icons/math-peak-reset.png +.. |math-peak-search| image:: ../../../../silx/resources/gui/icons/math-peak-search.png +.. |math-peak| image:: ../../../../silx/resources/gui/icons/math-peak.png +.. |math-sigma| image:: ../../../../silx/resources/gui/icons/math-sigma.png +.. |math-smooth| image:: ../../../../silx/resources/gui/icons/math-smooth.png +.. |math-substract| image:: ../../../../silx/resources/gui/icons/math-substract.png +.. |math-swap-sign| image:: ../../../../silx/resources/gui/icons/math-swap-sign.png +.. |math-ymin-to-zero| image:: ../../../../silx/resources/gui/icons/math-ymin-to-zero.png +.. |next| image:: ../../../../silx/resources/gui/icons/next.png +.. |normal| image:: ../../../../silx/resources/gui/icons/normal.png +.. |pixel-intensities| image:: ../../../../silx/resources/gui/icons/pixel-intensities.png +.. |plot-grid| image:: ../../../../silx/resources/gui/icons/plot-grid.png +.. |plot-roi-above| image:: ../../../../silx/resources/gui/icons/plot-roi-above.png +.. |plot-roi-below| image:: ../../../../silx/resources/gui/icons/plot-roi-below.png +.. |plot-roi-between| image:: ../../../../silx/resources/gui/icons/plot-roi-between.png +.. |plot-roi-reset| image:: ../../../../silx/resources/gui/icons/plot-roi-reset.png +.. |plot-roi| image:: ../../../../silx/resources/gui/icons/plot-roi.png +.. |plot-toggle-points| image:: ../../../../silx/resources/gui/icons/plot-toggle-points.png +.. |plot-widget| image:: ../../../../silx/resources/gui/icons/plot-widget.png +.. |plot-window-image| image:: ../../../../silx/resources/gui/icons/plot-window-image.png +.. |plot-window| image:: ../../../../silx/resources/gui/icons/plot-window.png +.. |plot-xauto| image:: ../../../../silx/resources/gui/icons/plot-xauto.png +.. |plot-xlog| image:: ../../../../silx/resources/gui/icons/plot-xlog.png +.. |plot-yauto| image:: ../../../../silx/resources/gui/icons/plot-yauto.png +.. |plot-ydown| image:: ../../../../silx/resources/gui/icons/plot-ydown.png +.. |plot-ylog| image:: ../../../../silx/resources/gui/icons/plot-ylog.png +.. |plot-yup| image:: ../../../../silx/resources/gui/icons/plot-yup.png +.. |previous| image:: ../../../../silx/resources/gui/icons/previous.png +.. |profile1D| image:: ../../../../silx/resources/gui/icons/profile1D.png +.. |profile2D| image:: ../../../../silx/resources/gui/icons/profile2D.png +.. |remove| image:: ../../../../silx/resources/gui/icons/remove.png +.. |rudder| image:: ../../../../silx/resources/gui/icons/rudder.png +.. |selected| image:: ../../../../silx/resources/gui/icons/selected.png +.. |shape-circle-solid| image:: ../../../../silx/resources/gui/icons/shape-circle-solid.png +.. |shape-circle| image:: ../../../../silx/resources/gui/icons/shape-circle.png +.. |shape-diagonal| image:: ../../../../silx/resources/gui/icons/shape-diagonal.png +.. |shape-ellipse-solid| image:: ../../../../silx/resources/gui/icons/shape-ellipse-solid.png +.. |shape-ellipse| image:: ../../../../silx/resources/gui/icons/shape-ellipse.png +.. |shape-horizontal| image:: ../../../../silx/resources/gui/icons/shape-horizontal.png +.. |shape-polygon| image:: ../../../../silx/resources/gui/icons/shape-polygon.png +.. |shape-rectangle| image:: ../../../../silx/resources/gui/icons/shape-rectangle.png +.. |shape-square| image:: ../../../../silx/resources/gui/icons/shape-square.png +.. |shape-vertical| image:: ../../../../silx/resources/gui/icons/shape-vertical.png +.. |silx| image:: ../../../../silx/resources/gui/icons/silx.png +.. |sliders-off| image:: ../../../../silx/resources/gui/icons/sliders-off.png +.. |sliders-on| image:: ../../../../silx/resources/gui/icons/sliders-on.png +.. |spec| image:: ../../../../silx/resources/gui/icons/spec.png +.. |test-png| image:: ../../../../silx/resources/gui/icons/test-png.png +.. |view-1d| image:: ../../../../silx/resources/gui/icons/view-1d.png +.. |view-2d-stack| image:: ../../../../silx/resources/gui/icons/view-2d-stack.png +.. |view-2d| image:: ../../../../silx/resources/gui/icons/view-2d.png +.. |view-3d| image:: ../../../../silx/resources/gui/icons/view-3d.png +.. |view-fullscreen| image:: ../../../../silx/resources/gui/icons/view-fullscreen.png +.. |view-nofullscreen| image:: ../../../../silx/resources/gui/icons/view-nofullscreen.png +.. |view-raw| image:: ../../../../silx/resources/gui/icons/view-raw.png +.. |view-refresh| image:: ../../../../silx/resources/gui/icons/view-refresh.png +.. |view-text| image:: ../../../../silx/resources/gui/icons/view-text.png +.. |window-new| image:: ../../../../silx/resources/gui/icons/window-new.png +.. |zoom-in| image:: ../../../../silx/resources/gui/icons/zoom-in.png +.. |zoom-original| image:: ../../../../silx/resources/gui/icons/zoom-original.png +.. |zoom-out| image:: ../../../../silx/resources/gui/icons/zoom-out.png +.. |zoom| image:: ../../../../silx/resources/gui/icons/zoom.png diff --git a/doc/source/modules/gui/index.rst b/doc/source/modules/gui/index.rst new file mode 100644 index 0000000..eecd124 --- /dev/null +++ b/doc/source/modules/gui/index.rst @@ -0,0 +1,21 @@ + +.. py:module:: silx.gui + +:mod:`silx.gui`: Graphical user interface +========================================= + +The ``silx.gui`` package provides a set of PyQt widgets. + + +.. toctree:: + :maxdepth: 1 + + console.rst + data/index.rst + fit/index.rst + hdf5/index.rst + icons.rst + plot/index.rst + plot3d/index.rst + qt.rst + widgets/index.rst diff --git a/doc/source/modules/gui/plot/dev.rst b/doc/source/modules/gui/plot/dev.rst new file mode 100644 index 0000000..707d215 --- /dev/null +++ b/doc/source/modules/gui/plot/dev.rst @@ -0,0 +1,204 @@ +Package structure +================= + +The :mod:`silx.gui.plot` package provides plot widgets. +This package is structured as follows. + +.. currentmodule:: silx.gui.plot + +:mod:`.PlotWidget` and :mod:`.PlotWindow` provides the user API. +:class:`PlotWidget` is a Qt widget (actually a :class:`QMainWindow`) displaying a 1D, 2D plot area. +It provides different interaction modes. +:class:`PlotWindow` is a Qt widget (actually a :class:`QMainWindow`) which adds a set of toolbar buttons and associated functionalities to :class:`PlotWidget`. +The toolbar QActions are implemented in :mod:`.PlotActions`. + +:mod:`.Plot`, :mod:`.PlotEvents` and :mod:`.PlotInteraction` implement the plotting API regardless of the rendering backend and regardless of its integration in Qt. +The plotting API in defined in :mod:`.Plot`. +The different interaction modes (zoom, drawing, pan) are implemented in :mod:`.PlotInteraction`. +Each interaction mode is implemented with a state machine structure (implemented in :mod:`.Interaction`). +The different events emitted by :class:`Plot` and by the interaction modes are created with helper functions defined in :mod:`.PlotEvents`. + +The :class:`PlotWindow` uses additional widgets: + +- :mod:`.ColormapDialog` to change colormap settings. +- :mod:`.CurvesROIWidget` to create regions of interest for curves +- :mod:`.LegendSelector` to display a list of curves legends which provides some control on the curves (e.g., select, delete). +- :mod:`.MaskToolsWidget` to provide tools to draw a mask on an image. +- :mod:`.ScatterMaskToolsWidget` to provide tools to draw a mask on a scatter. +- The :mod:`.PlotTools` module provides a set of additional widgets: + + - :class:`.PlotTools.PositionInfo` + - :class:`.PlotTools.LimitsToolBar` + +- The :mod:`.Profile` module provides toolbar for extracting profiles from image and image stack: + + - :class:`.Profile.ProfileToolBar` + - :class:`.Profile.Profile3DToolBar` + +- :mod:`silx.gui.console` to provide an IPython console which can control the plot area content. + +The widgets also use the following miscellaneous modules: + +- :mod:`.Colors` to convert colors from name to RGB(A) +- :mod:`.MPLColormap` to embed recent matplotlib colormaps: 'magma', 'inferno', 'plasma' and 'viridis'. +- :mod:`._utils`: utility functions + +The :mod:`backends` package provide the implementation of the rendering used by the :class:`Plot`. +It contains: +:mod:`.backends.BackendBase` defines the API any plot backend should provide in :class:`BackendBase`. +:mod:`.backends.BackendMatplotlib` implements a `matplotlib `_ backend. +It uses :mod:`.backends.ModestImage` to provide a faster matplotlib AxesImage class using nearest values. +The :mod:`.backends.BackendMatplotlib` the provides two classes: + +.. currentmodule:: silx.gui.plot.backends.BackendMatplotlib + +- :class:`BackendMatplotlib` that provides a matplotlib backend without a specific canvas. +- :class:`BackendMatplotlibQt` which inherits from :class:`BackendMatplotlib` and adds a Qt canvas, and Qt specific functionalities. + +The OpenGL-based backend is implemented in the :mod:`.backends.BackendOpenGL` module and +the :mod:`.backends.glutils` package which provides the different primitives used for rendering and interaction. +It is based on :mod:`silx.gui._glutils`, `PyOpenGL `_ and OpenGL >= 2.1. + +.. |Plot and backend| image:: img/plot_and_backend.png + :align: middle + +|Plot and backend| + +Modules +======= + +.. currentmodule:: silx.gui.plot + +For :mod:`.PlotWidget` and :mod:`.Plot` modules, see their respective documentations: :mod:`.PlotWidget`, :mod:`.Plot`. + +The following modules are the modules used internally by the plot package. + +:mod:`backends.BackendBase` ++++++++++++++++++++++++++++ + +.. currentmodule:: silx.gui.plot.backends.BackendBase + +.. automodule:: silx.gui.plot.backends.BackendBase + :members: + +:mod:`backends.BackendMatplotlib` ++++++++++++++++++++++++++++++++++ + +.. currentmodule:: silx.gui.plot.backends.BackendMatplotlib + +.. automodule:: silx.gui.plot.backends.BackendMatplotlib + :members: + +:mod:`backends.ModestImage` ++++++++++++++++++++++++++++ + +.. currentmodule:: silx.gui.plot.backends.ModestImage + +.. automodule:: silx.gui.plot.backends.ModestImage + :members: + :undoc-members: + +:mod:`ColormapDialog` ++++++++++++++++++++++ + +.. currentmodule:: silx.gui.plot.ColormapDialog + +.. automodule:: silx.gui.plot.ColormapDialog + :members: + +:mod:`Colors` ++++++++++++++ + +.. currentmodule:: silx.gui.plot.Colors + +.. automodule:: silx.gui.plot.Colors + :members: rgba + +:mod:`CurvesROIWidget` +++++++++++++++++++++++ + +.. currentmodule:: silx.gui.plot.CurvesROIWidget + +.. automodule:: silx.gui.plot.CurvesROIWidget + :members: + +:mod:`Interaction` +++++++++++++++++++ + +.. currentmodule:: silx.gui.plot.Interaction + +.. automodule:: silx.gui.plot.Interaction + :members: + +:mod:`LegendSelector` ++++++++++++++++++++++ + +.. currentmodule:: silx.gui.plot.LegendSelector + +.. automodule:: silx.gui.plot.LegendSelector + :members: + +:mod:`_BaseMaskToolsWidget` ++++++++++++++++++++++++++++ + +.. currentmodule:: silx.gui.plot._BaseMaskToolsWidget + +.. automodule:: silx.gui.plot._BaseMaskToolsWidget + :members: + +:mod:`MaskToolsWidget` +++++++++++++++++++++++ + +.. currentmodule:: silx.gui.plot.MaskToolsWidget + +.. automodule:: silx.gui.plot.MaskToolsWidget + :members: + :show-inheritance: + +:mod:`ScatterMaskToolsWidget` ++++++++++++++++++++++++++++++ + +.. currentmodule:: silx.gui.plot.ScatterMaskToolsWidget + +.. automodule:: silx.gui.plot.ScatterMaskToolsWidget + :members: + :show-inheritance: + +:mod:`MPLColormap` +++++++++++++++++++ + +.. currentmodule:: silx.gui.plot.MPLColormap + +.. automodule:: silx.gui.plot.MPLColormap + :members: + +:mod:`PlotEvents` ++++++++++++++++++ + +.. currentmodule:: silx.gui.plot.PlotEvents + +.. automodule:: silx.gui.plot.PlotEvents + :members: + :undoc-members: + +:mod:`PlotInteraction` +++++++++++++++++++++++ + +.. currentmodule:: silx.gui.plot.PlotInteraction + +.. automodule:: silx.gui.plot.PlotInteraction + :members: + +:mod:`_utils` ++++++++++++++ + +.. currentmodule:: silx.gui.plot._utils + +.. automodule:: silx.gui.plot._utils + :members: + +:mod:`ticklayout` +----------------- + +.. automodule:: silx.gui.plot._utils.ticklayout + :members: \ No newline at end of file diff --git a/doc/source/modules/gui/plot/getting_started.rst b/doc/source/modules/gui/plot/getting_started.rst new file mode 100644 index 0000000..9e45b70 --- /dev/null +++ b/doc/source/modules/gui/plot/getting_started.rst @@ -0,0 +1,491 @@ +.. currentmodule:: silx.gui + +Getting started with plot widgets +================================= + +This introduction to :mod:`silx.gui.plot` covers the following topics: + +- `Use silx.gui.plot from the console`_ +- `Use silx.gui.plot from a script`_ +- `Plot curves in a widget`_ +- `Plot images in a widget`_ +- `Control plot axes`_ + +For a complete description of the API, see :mod:`silx.gui.plot`. + +Use :mod:`silx.gui.plot` from the console +----------------------------------------- + +From IPython +++++++++++++ + +To run :mod:`silx.gui.plot` widgets from `IPython `_, IPython must be set to use Qt (and in case of using PyQt4 and Python 2.7, PyQt must be set ti use API version 2, see Explanation_ below). + +As *silx* is performing some configuration of the Qt binding and `matplotlib `_, the safest way to use *silx* from IPython is to import :mod:`silx.gui.plot` first and then run either `%gui `_ qt or `%pylab `_ qt:: + + In [1]: from silx.gui.plot import * + In [2]: %pylab qt + +Alternatively, when using Python 2.7 and PyQt4, you can start IPython with the ``QT_API`` environment variable set to ``pyqt``. + +On Linux and MacOS X, run:: + + QT_API=pyqt ipython + +On Windows, run from the command line:: + + set QT_API=pyqt&&ipython + + +Explanation +........... + +PyQt4 used from Python 2.x provides 2 incompatible versions of QString and QVariant: + +- version 1, the legacy which is the default, and +- version 2, a more pythonic one, which is the only one supported by *silx*. + +All other configurations (i.e., PyQt4 on Python 3.x, PySide, PyQt5, IPython QtConsole widget) uses version 2 only or as the default. + +For more information, see `IPython, PyQt and PySide `_. + + +From Python ++++++++++++ + +The :mod:`silx.sx` package is a convenient module to use silx from the console. +It sets-up Qt and provides functions for the main features of silx. + +>>> from silx import sx + +Alternatively, you can create a QApplication before using silx widgets: + +>>> from silx.gui import qt # Import Qt binding and do some set-up +>>> qapp = qt.QApplication([]) + +>>> from silx.gui.plot import * # Import plot widgets and set-up matplotlib + +.. currentmodule:: silx.sx + +Plot functions +++++++++++++++ + +The :mod:`silx.sx` package provides 2 functions to plot curves and images from the (I)Python console in a widget with a set of tools: + +- :func:`plot`, and +- :func:`imshow`. + +For more features, use widgets directly (see `Plot curves in a widget`_ and `Plot images in a widget`_). + + +Curve: :func:`plot` +................... + +The following examples must run with a Qt QApplication initialized (see `Use silx.gui.plot from the console`_). + +First import :mod:`sx` function: + +>>> from silx import sx +>>> import numpy + +Plot a single curve given some values: + +>>> values = numpy.random.random(100) +>>> plot_1curve = sx.plot(values, title='Random data') + +Plot a single curve given the x and y values: + +>>> angles = numpy.linspace(0, numpy.pi, 100) +>>> sin_a = numpy.sin(angles) +>>> plot_sinus = sx.plot(angles, sin_a, +... xlabel='angle (radian)', ylabel='sin(a)') + +Plot many curves by giving a 2D array, provided xn, yn arrays: + +>>> plot_curves = sx.plot(x0, y0, x1, y1, x2, y2, ...) + +Plot curve with style giving a style string: + +>>> plot_styled = sx.plot(x0, y0, 'ro-', x1, y1, 'b.') + +See :func:`plot` for details. + + +Image: :func:`imshow` +..................... + +This example plot a single image. + +First, import :mod:`silx.sx`: + +>>> from silx import sx +>>> import numpy + +>>> data = numpy.random.random(1024 * 1024).reshape(1024, 1024) +>>> plt = sx.imshow(data, title='Random data') + +See :func:`imshow` for more details. + + +Use :mod:`silx.gui.plot` from a script +-------------------------------------- + +A Qt GUI script must have a QApplication initialized before creating widgets: + +.. code-block:: python + + from silx.gui import qt + + [...] + + qapp = qt.QApplication([]) + + [...] # Widgets initialisation + + if __name__ == '__main__': + [...] + qapp.exec_() + +Unless a Qt binding has already been loaded, :mod:`silx.gui.qt` uses the first Qt binding it founds by probing in the following order: PyQt5, PyQt4 and finally PySide. +If you prefer to choose the Qt binding yourself, import it before importing +a module from :mod:`silx.gui`: + +.. code-block:: python + + import PySide # Importing PySide will force silx to use it + from silx.gui import qt + + +.. warning:: + :mod:`silx.gui.plot` widgets are not thread-safe. + All calls to :mod:`silx.gui.plot` widgets must be made from the main thread. + +Plot curves in a widget +----------------------- + +The :class:`Plot1D` widget provides a plotting area and a toolbar with tools useful for curves such as setting logarithmic scale or defining region of interest. + +First, create a :class:`Plot1D` widget: + +.. code-block:: python + + from silx.gui.plot import Plot1D + + plot = Plot1D() # Create the plot widget + plot.show() # Make the plot widget visible + + +One curve ++++++++++ + +To display a single curve, use the :meth:`.PlotWidget.addCurve` method: + +.. code-block:: python + + plot.addCurve(x=(1, 2, 3), y=(3, 2, 1)) # Add a curve with default style + +When you need to update this curve, call :meth:`.PlotWidget.addCurve` again with the new values to display: + +.. code-block:: python + + plot.addCurve(x=(1, 2, 3), y=(1, 2, 3)) # Replace the existing curve + +To clear the plotting area, call :meth:`.PlotWidget.clear`: + +.. code-block:: python + + plot.clear() + + +Multiple curves ++++++++++++++++ + +In order to display multiple curves at the same time, you need to provide a different ``legend`` string for each of them: + +.. code-block:: python + + import numpy + + x = numpy.linspace(-numpy.pi, numpy.pi, 1000) + plot.addCurve(x, numpy.sin(x), legend='sinus') + plot.addCurve(x, numpy.cos(x), legend='cosinus') + plot.addCurve(x, numpy.random.random(len(x)), legend='random') + + +To update a curve, call :meth:`.PlotWidget.addCurve` with the ``legend`` of the curve you want to udpdate. +By default, the new curve will keep the same color (and style) as the curve it is updating: + +.. code-block:: python + + plot.addCurve(x, numpy.random.random(len(x)) - 1., legend='random') + +To remove a curve from the plot, call :meth:`.PlotWidget.remove` with the ``legend`` of the curve you want to remove from the plot: + +.. code-block:: python + + plot.remove('random') + +To clear the plotting area, call :meth:`.PlotWidget.clear`: + +.. code-block:: python + + plot.clear() + +Curve style ++++++++++++ + +By default, different curves will automatically use different styles to render, and keep the same style when updated. + +It is possible to specify the ``color`` of the curve, its ``linewidth`` and ``linestyle`` as well as the ``symbol`` to use as markers for data points (See :meth:`.PlotWidget.addCurve` for more details): + +.. code-block:: python + + import numpy + + x = numpy.linspace(-numpy.pi, numpy.pi, 100) + + # Curve with a thick dashed line + plot.addCurve(x, numpy.sin(x), legend='sinus', + linewidth=3, linestyle='--') + + # Curve with pink markers only + plot.addCurve(x, numpy.cos(x), legend='cosinus', + color='pink', linestyle=' ', symbol='o') + + # Curve with green line with square markers + plot.addCurve(x, numpy.random.random(len(x)), legend='random', + color='green', linestyle='-', symbol='s') + + + +Histogram ++++++++++ + +Data can be displayed as an histogram. This must be specified when calling the the addCurve function. (using ``histogram``, See :meth:`.PlotWidget.addCurve` for more details ). + +Histogram steps can be centered on x values or set at the left or the right of the given x values. + +.. code-block:: python + + import numpy + x = numpy.arange(0, 20, 1) + plot.addCurve(x, x+1, histogram='center', fill=True, color='green') + +.. note:: You can also give x as edges. For this you must have len(x) = len(y) + 1 + +Plot images in a widget +----------------------- + +The :class:`Plot2D` widget provides a plotting area and a toolbar with tools useful for images, such as keeping aspect ratio, changing the colormap or defining a mask. + +First, create a :class:`Plot2D` widget: + +.. code-block:: python + + from silx.gui.plot import Plot2D + + plot = Plot2D() # Create the plot widget + plot.show() # Make the plot widget visible + + +One image ++++++++++ + +To display a single image, use the :meth:`.PlotWidget.addImage` method: + +.. code-block:: python + + import numpy + + data = numpy.random.random(512 * 512).reshape(512, -1) # Create 2D image + plot.addImage(data) # Plot the 2D data set with default colormap + + +To update this image, call :meth:`.PlotWidget.addImage` again with the new image to display: + +.. code-block:: python + + # Create a RGB image + rgb_image = (numpy.random.random(512*512*3) * 255).astype(numpy.uint8) + rgb_image.shape = 512, 512, 3 + + plot.addImage(rgb_image) # Plot the RGB image instead of the previous data + + +To clear the plotting area, call :meth:`.PlotWidget.clear`: + +.. code-block:: python + + plot.clear() + + +Origin and scale +++++++++++++++++ + +:meth:`.PlotWidget.addImage` supports both 2D arrays of data displayed with a colormap and RGB(A) images as 3D arrays of shape (height, width, color channels). + +When displaying an image, it is possible to specify the ``origin`` and the ``scale`` of the image array in the plot area coordinates: + +.. code-block:: python + + data = numpy.random.random(512 * 512).reshape(512, -1) + plot.addImage(data, origin=(100, 100), scale=(0.1, 0.1)) + +When updating an image, if ``origin`` and ``scale`` are not provided, the previous values will be used: + +.. code-block:: python + + data = numpy.random.random(512 * 512).reshape(512, -1) + plot.addImage(data) # Keep previous origin and scale + + +Colormap +++++++++ + +A ``colormap`` is described with a :class:`dict` as follows (See :mod:`silx.gui.plot.Plot` for full documentation of the colormap): + +.. code-block:: python + + colormap = { + 'name': 'gray', # Name of the colormap + 'normalization': 'linear', # Either 'linear' or 'log' + 'autoscale': True, # True to autoscale colormap to data range, False to use [vmin, vmax] + 'vmin': 0.0, # If not autoscale, data value to bind to min of colormap + 'vmax': 1.0 # If not autoscale, data value to bind to max of colormap + } + + +At least the following colormap names are guaranteed to be available, but any colormap name from `matplotlib `_ (see `Choosing Colormaps `_) should work: + +- gray +- reversed gray +- temperature +- red +- green +- blue +- viridis +- magma +- inferno +- plasma + +It is possible to change the default colormap of :meth:`.PlotWidget.addImage` for the plot widget with :meth:`.PlotWidget.setDefaultColormap` (and to get it with :meth:`.PlotWidget.getDefaultColormap`): + +.. code-block:: python + + colormap = {'name': 'viridis', 'normalization': 'linear', + 'autoscale': True, 'vmin': 0.0, 'vmax': 1.0} + plot.setDefaultColormap(colormap) + + data = numpy.arange(512 * 512.).reshape(512, -1) + plot.addImage(data) # Rendered with the default colormap set before + +It is also possible to provide a ``colormap`` to :meth:`.PlotWidget.addImage` to override this default for an image: + +.. code-block:: python + + colormap = {'name': 'magma', 'normalization': 'log', + 'autoscale': False, 'vmin': 1.2, 'vmax': 1.8} + data = numpy.random.random(512 * 512).reshape(512, -1) + 1. + plot.addImage(data, colormap=colormap) + +As for `Origin and scale`_, when updating an image, if ``colormap`` is not provided, the previous colormap will be used: + +.. code-block:: python + + data = numpy.random.random(512 * 512).reshape(512, -1) + 1. + plot.addImage(data) # Keep previous colormap + +The colormap can be changed by the user from the widget's toolbar. + + +Multiple images ++++++++++++++++ + +In order to display multiple images at the same time, you need to provide a different ``legend`` string for each of them and to set the ``replace`` argument to ``False``: + +.. code-block:: python + + data = numpy.random.random(512 * 512).reshape(512, -1) + plot.addImage(data, legend='random', replace=False) + + data = numpy.arange(512 * 512.).reshape(512, -1) + plot.addImage(data, legend='arange', replace=False, origin=(512, 512)) + + +To update an image, call :meth:`.PlotWidget.addImage` with the ``legend`` of the curve you want to udpdate. +By default, the new image will keep the same colormap, origin and scale as the image it is updating: + +.. code-block:: python + + data = (512 * 512. - numpy.arange(512 * 512.)).reshape(512, -1) + plot.addImage(data, legend='arange', replace=False) # Beware of replace=False + + +To remove an image from the plot, call :meth:`.PlotWidget.remove` with the ``legend`` of the image you want to remove: + +.. code-block:: python + + plot.remove('random') + + +Control plot axes +----------------- + +The following examples illustrate the API to control the plot axes. + +Labels and title +++++++++++++++++ + +Use :meth:`.PlotWidget.setGraphTitle` to set the plot main title. +Use :meth:`.PlotWidget.setGraphXLabel` and :meth:`.PlotWidget.setGraphYLabel` to set the axes text labels: + +.. code-block:: python + + plot.setGraphTitle('My plot') + plot.setGraphXLabel('X') + plot.setGraphYLabel('Y') + + +Axes limits ++++++++++++ + +Different methods allows to get and set the data limits displayed on each axis. + +The following code moves the visible plot area to the right: + +.. code-block:: python + + xmin, xmax = plot.getGraphXLimits() + offset = 0.1 * (xmax - xmin) + plot.setGraphXLimits(xmin + offset, xmax + offset) + +:meth:`.PlotWidget.resetZoom` set the plot limits to the bounds of the data: + +.. code-block:: python + + plot.resetZoom() + +See :meth:`.PlotWidget.resetZoom`, :meth:`.PlotWidget.setLimits`, :meth:`.PlotWidget.getGraphXLimits`, :meth:`.PlotWidget.setGraphXLimits`, :meth:`.PlotWidget.getGraphYLimits`, :meth:`.PlotWidget.setGraphYLimits` for details. + + +Axes +++++ + +Different methods allow plot axes modifications: + +.. code-block:: python + + plot.setYAxisInverted(True) # Makes the Y axis pointing downward + plot.setKeepDataAspectRatio(True) # To keep aspect ratio between X and Y axes + +See :meth:`.PlotWidget.setYAxisInverted`, :meth:`.PlotWidget.setKeepDataAspectRatio` for details. + +.. code-block:: python + + plot.setGraphGrid(which='both') # To show a grid for both minor and major axes ticks + + # Use logarithmic axes + plot.setXAxisLogarithmic(True) + plot.setYAxisLogarithmic(True) + +See :meth:`.PlotWidget.setGraphGrid`, :meth:`.PlotWidget.setXAxisLogarithmic`, :meth:`.PlotWidget.setYAxisLogarithmic` for details. diff --git a/doc/source/modules/gui/plot/imageview.rst b/doc/source/modules/gui/plot/imageview.rst new file mode 100644 index 0000000..c2663c7 --- /dev/null +++ b/doc/source/modules/gui/plot/imageview.rst @@ -0,0 +1,15 @@ + +.. currentmodule:: silx.gui.plot + +:mod:`ImageView`: Plot an image with side histograms +==================================================== + +.. automodule:: silx.gui.plot.ImageView + +.. currentmodule:: silx.gui.plot.ImageView + +:class:`ImageView` class +------------------------ + +.. autoclass:: ImageView + :members: valueChanged, profile, setImage, getColormap, setColormap, getHistogram, setGraphTitle, setGraphXLabel, setGraphYLabel diff --git a/doc/source/modules/gui/plot/img/ImageView.png b/doc/source/modules/gui/plot/img/ImageView.png new file mode 100644 index 0000000..170466c Binary files /dev/null and b/doc/source/modules/gui/plot/img/ImageView.png differ diff --git a/doc/source/modules/gui/plot/img/LimitsToolBar.png b/doc/source/modules/gui/plot/img/LimitsToolBar.png new file mode 100644 index 0000000..99af8bd Binary files /dev/null and b/doc/source/modules/gui/plot/img/LimitsToolBar.png differ diff --git a/doc/source/modules/gui/plot/img/Plot1D.png b/doc/source/modules/gui/plot/img/Plot1D.png new file mode 100644 index 0000000..9417d77 Binary files /dev/null and b/doc/source/modules/gui/plot/img/Plot1D.png differ diff --git a/doc/source/modules/gui/plot/img/Plot2D.png b/doc/source/modules/gui/plot/img/Plot2D.png new file mode 100644 index 0000000..e00de28 Binary files /dev/null and b/doc/source/modules/gui/plot/img/Plot2D.png differ diff --git a/doc/source/modules/gui/plot/img/PlotWidget.png b/doc/source/modules/gui/plot/img/PlotWidget.png new file mode 100644 index 0000000..2ecc73f Binary files /dev/null and b/doc/source/modules/gui/plot/img/PlotWidget.png differ diff --git a/doc/source/modules/gui/plot/img/PlotWindow.png b/doc/source/modules/gui/plot/img/PlotWindow.png new file mode 100644 index 0000000..86acc52 Binary files /dev/null and b/doc/source/modules/gui/plot/img/PlotWindow.png differ diff --git a/doc/source/modules/gui/plot/img/PositionInfo.png b/doc/source/modules/gui/plot/img/PositionInfo.png new file mode 100644 index 0000000..5572f53 Binary files /dev/null and b/doc/source/modules/gui/plot/img/PositionInfo.png differ diff --git a/doc/source/modules/gui/plot/img/StackView.png b/doc/source/modules/gui/plot/img/StackView.png new file mode 100644 index 0000000..4ed2a68 Binary files /dev/null and b/doc/source/modules/gui/plot/img/StackView.png differ diff --git a/doc/source/modules/gui/plot/img/StackViewMainWindow.png b/doc/source/modules/gui/plot/img/StackViewMainWindow.png new file mode 100644 index 0000000..e1e900a Binary files /dev/null and b/doc/source/modules/gui/plot/img/StackViewMainWindow.png differ diff --git a/doc/source/modules/gui/plot/img/colorScale.png b/doc/source/modules/gui/plot/img/colorScale.png new file mode 100644 index 0000000..162ce3f Binary files /dev/null and b/doc/source/modules/gui/plot/img/colorScale.png differ diff --git a/doc/source/modules/gui/plot/img/colorScaleBar.png b/doc/source/modules/gui/plot/img/colorScaleBar.png new file mode 100644 index 0000000..e57ce0b Binary files /dev/null and b/doc/source/modules/gui/plot/img/colorScaleBar.png differ diff --git a/doc/source/modules/gui/plot/img/fftAction0.png b/doc/source/modules/gui/plot/img/fftAction0.png new file mode 100644 index 0000000..5bd8061 Binary files /dev/null and b/doc/source/modules/gui/plot/img/fftAction0.png differ diff --git a/doc/source/modules/gui/plot/img/fftAction1.png b/doc/source/modules/gui/plot/img/fftAction1.png new file mode 100644 index 0000000..e4b20d7 Binary files /dev/null and b/doc/source/modules/gui/plot/img/fftAction1.png differ diff --git a/doc/source/modules/gui/plot/img/linearColorbar.png b/doc/source/modules/gui/plot/img/linearColorbar.png new file mode 100644 index 0000000..26621ce Binary files /dev/null and b/doc/source/modules/gui/plot/img/linearColorbar.png differ diff --git a/doc/source/modules/gui/plot/img/logColorbar.png b/doc/source/modules/gui/plot/img/logColorbar.png new file mode 100644 index 0000000..cdd247c Binary files /dev/null and b/doc/source/modules/gui/plot/img/logColorbar.png differ diff --git a/doc/source/modules/gui/plot/img/netCounts.png b/doc/source/modules/gui/plot/img/netCounts.png new file mode 100644 index 0000000..f987d1f Binary files /dev/null and b/doc/source/modules/gui/plot/img/netCounts.png differ diff --git a/doc/source/modules/gui/plot/img/plot_and_backend.png b/doc/source/modules/gui/plot/img/plot_and_backend.png new file mode 100644 index 0000000..6c36c4f Binary files /dev/null and b/doc/source/modules/gui/plot/img/plot_and_backend.png differ diff --git a/doc/source/modules/gui/plot/img/rawCounts.png b/doc/source/modules/gui/plot/img/rawCounts.png new file mode 100644 index 0000000..fa36b8e Binary files /dev/null and b/doc/source/modules/gui/plot/img/rawCounts.png differ diff --git a/doc/source/modules/gui/plot/img/roiwidget.png b/doc/source/modules/gui/plot/img/roiwidget.png new file mode 100644 index 0000000..35ef7f1 Binary files /dev/null and b/doc/source/modules/gui/plot/img/roiwidget.png differ diff --git a/doc/source/modules/gui/plot/img/shiftAction0.png b/doc/source/modules/gui/plot/img/shiftAction0.png new file mode 100644 index 0000000..2d5837a Binary files /dev/null and b/doc/source/modules/gui/plot/img/shiftAction0.png differ diff --git a/doc/source/modules/gui/plot/img/shiftAction3.png b/doc/source/modules/gui/plot/img/shiftAction3.png new file mode 100644 index 0000000..a2187b8 Binary files /dev/null and b/doc/source/modules/gui/plot/img/shiftAction3.png differ diff --git a/doc/source/modules/gui/plot/img/tickbar.png b/doc/source/modules/gui/plot/img/tickbar.png new file mode 100644 index 0000000..214fec7 Binary files /dev/null and b/doc/source/modules/gui/plot/img/tickbar.png differ diff --git a/doc/source/modules/gui/plot/index.rst b/doc/source/modules/gui/plot/index.rst new file mode 100644 index 0000000..143b85b --- /dev/null +++ b/doc/source/modules/gui/plot/index.rst @@ -0,0 +1,130 @@ + +.. currentmodule:: silx.gui + +:mod:`plot`: 1D and 2D Plot widgets +=================================== + +.. toctree:: + :hidden: + + getting_started.rst + +.. currentmodule:: silx.gui.plot + +.. automodule:: silx.gui.plot + +For an introduction to the widgets of this package, see :doc:`getting_started`. + +For examples of custom plot actions, see :doc:`plotactions_examples`. + +Widgets gallery +--------------- + +The :mod:`silx.gui.plot` package provides the following plotting widgets: + +.. |imgPlotWidget| image:: img/PlotWidget.png + :height: 150px + :align: middle + +.. |imgPlotWindow| image:: img/PlotWindow.png + :height: 150px + :align: middle + +.. |imgPlot1D| image:: img/Plot1D.png + :height: 150px + :align: middle + +.. |imgPlot2D| image:: img/Plot2D.png + :height: 150px + :align: middle + +.. |imgImageView| image:: img/ImageView.png + :height: 150px + :align: middle + +.. |imgStackView| image:: img/StackView.png + :height: 150px + :align: middle + +.. list-table:: + :widths: 1 4 + :header-rows: 1 + + * - Widget + - Description + * - |imgPlotWidget| + - :class:`PlotWidget` is the base Qt widget providing a plot area. + Other plot widgets are based on this one and provides the same API. + * - |imgPlotWindow| + - :class:`PlotWindow` adds a toolbar to :class:`PlotWidget`. + The content of this toolbar can be configured from the + :class:`PlotWindow` constructor or by hiding its content afterward. + * - |imgPlot1D| + - :class:`.Plot1D` is a :class:`PlotWindow` configured with tools useful + for curves. + * - |imgPlot2D| + - :class:`.Plot2D` is a :class:`PlotWindow` configured with tools useful + for images. + * - |imgImageView| + - :class:`ImageView` adds side histograms to a :class:`.Plot2D` widget. + * - |imgStackView| + - :class:`StackView` is a widget designed to display an image from a + stack of images in a :class:`PlotWindow` widget, with a frame browser + to navigate in the stack. The profile tool can do a 2D profile on the + stack of images. + +It also provides (and uses) widgets that can be attached to a :class:`PlotWidget`: + +.. |imgPositionInfo| image:: img/PositionInfo.png + :width: 300px + :align: middle + +.. |imgLimitsToolBar| image:: img/LimitsToolBar.png + :width: 300px + :align: middle + +.. |imgColorbar| image:: img/logColorbar.png + :height: 150px + :align: middle + + +.. list-table:: + :widths: 1 4 + :header-rows: 1 + + * - Widget + - Description + * - |imgPositionInfo| + - :class:`.PlotTools.PositionInfo` is a widget displaying mouse position and + information of a :class:`PlotWidget` associated to the mouse position. + * - |imgLimitsToolBar| + - :class:`.PlotTools.LimitsToolBar` is a QToolBar displaying and + controlling the limits of a :class:`PlotWidget`. + * - |imgColorbar| + - :class:`.ColorBar.ColorBarWidget` display colormap gradient and can be linked with a plot + to display the colormap + +Public modules +-------------- + +.. toctree:: + :maxdepth: 2 + + plotwidget.rst + plotwindow.rst + imageview.rst + stackview.rst + plot.rst + items.rst + plotactions.rst + plottools.rst + profile.rst + roi.rst + +Internals +--------- + +.. toctree:: + :maxdepth: 2 + + dev.rst diff --git a/doc/source/modules/gui/plot/items.rst b/doc/source/modules/gui/plot/items.rst new file mode 100644 index 0000000..beba3a1 --- /dev/null +++ b/doc/source/modules/gui/plot/items.rst @@ -0,0 +1,63 @@ + +.. currentmodule:: silx.gui.plot + +:mod:`items`: Plot primitives +============================= + +.. automodule:: silx.gui.plot.items + +.. currentmodule:: silx.gui.plot.items + +Curve +----- + +.. autoclass:: Curve + :members: + :inherited-members: + +Images +------ + +.. autoclass:: ImageData + :members: + :inherited-members: + +.. autoclass:: ImageRgba + :members: + :inherited-members: + +Scatter +------- + +.. autoclass:: Scatter + :members: + :inherited-members: + +Histogram +--------- + +.. autoclass:: Histogram + :members: + :inherited-members: + +Markers +------- + +.. autoclass:: Marker + :members: + :inherited-members: + +.. autoclass:: XMarker + :members: + :inherited-members: + +.. autoclass:: YMarker + :members: + :inherited-members: + +Item +---- + +.. autoclass:: Shape + :members: + :inherited-members: diff --git a/doc/source/modules/gui/plot/plot.rst b/doc/source/modules/gui/plot/plot.rst new file mode 100644 index 0000000..2b8e096 --- /dev/null +++ b/doc/source/modules/gui/plot/plot.rst @@ -0,0 +1,16 @@ + +.. currentmodule:: silx.gui.plot + +:mod:`Plot`: Full plot API +========================== + +.. automodule:: silx.gui.plot.Plot + +.. currentmodule:: silx.gui.plot.Plot + +:class:`Plot` class +------------------- + +.. autoclass:: Plot + :show-inheritance: + :members: diff --git a/doc/source/modules/gui/plot/plotactions.rst b/doc/source/modules/gui/plot/plotactions.rst new file mode 100644 index 0000000..29a3656 --- /dev/null +++ b/doc/source/modules/gui/plot/plotactions.rst @@ -0,0 +1,20 @@ + +.. currentmodule:: silx.gui.plot + +:mod:`PlotActions`: Actions for PlotWidget +=========================================== + +.. currentmodule:: silx.gui.plot.PlotActions + +The :class:`PlotAction` is a base class used to define plot actions. + +Plot actions serve to add menu items or toolbar items that are associated with a method +that can interact with the associated :class:`PlotWidget`. + +For an introduction to creating custom plot actions, see :doc:`plotactions_examples`. + +PlotActions API +--------------- + +.. automodule:: silx.gui.plot.PlotActions + :members: diff --git a/doc/source/modules/gui/plot/plotactions_examples.rst b/doc/source/modules/gui/plot/plotactions_examples.rst new file mode 100644 index 0000000..f14a42a --- /dev/null +++ b/doc/source/modules/gui/plot/plotactions_examples.rst @@ -0,0 +1,93 @@ +.. currentmodule:: silx.gui + +Adding custom plot actions +========================== + +A :class:`PlotWindow` defines a number of standard plot actions that can be executed +by clicking on toolbar icons. + +Developers can design additional plot actions to be added as toolbar icons or as menu entries, +to be added to a :class:`PlotWindow` or to design their own plot window based on +:class:`PlotWidget`. + +This documentation pages provides examples on how to do this. + +Simple example: Shift a curve +----------------------------- + +The following script is a simplistic example to show the basic required steps: + + - create a new class inheriting from :class:`silx.gui.plot.PlotActions.PlotAction` + - define basic parameters such as the icon, the tooltip... + - write a method that will be triggered by the action + - initialize the new plot action by passing a reference to a plot window + - add the action to a toolbar or a menu + +The method implemented in this action interacts with the plot in a basic way. It gets the active curve, +then it creates a new data array based on the curve data, and finally it replaces the original curve +with a new one using the modified data array. + +.. literalinclude:: ../../../../../examples/shiftPlotAction.py + :lines: 36- + +.. |imgShiftAction0| image:: img/shiftAction0.png + :height: 300px + :align: middle + +.. |imgShiftAction3| image:: img/shiftAction3.png + :height: 300px + :align: middle + +.. list-table:: + :widths: 1 2 + + * - |imgShiftAction0| + - Initial state + * - |imgShiftAction3| + - After triggering the action 3 times, the selected triangle shaped curve + is shifted up by 3 units + +Advanced example: Display amplitude spectrum +-------------------------------------------- + +This more advanced example shows additional ways of interacting with the plot, by changing +labels, storing additional data array along with the curve data. + +This action is *checkable*, meaning that is has two states. When clicking the toolbar icon +or the menu item, it remains in a *pushed* state until it is clicked again. + +In one state (*un-checked*), the original data is displayed. In the other state, the amplitude +spectrum of the original signal is displayed. When the state is changed, the triggered action +computes either the Fast Fourier Transform (FFT), or the reverse FFT. + +This example also illustrates how to store additional data, along with a curve. +The FFT computation returns complex values, but we want to display real data, so we compute +the amplitude spectrum. However, the inverse FFT requires the complete FFT data as input. +We are therefore required to store the complex array of FFT data as curve metadata, +in order to be able to reverse the process when the action is unchecked. + +.. literalinclude:: ../../../../../examples/fftPlotAction.py + :lines: 44- + +.. |imgFftAction0| image:: img/fftAction0.png + :height: 300px + :align: middle + +.. |imgFftAction1| image:: img/fftAction1.png + :height: 300px + :align: middle + +.. list-table:: + :widths: 1 2 + + * - |imgFftAction0| + - Original signals (zoom applied). In red, a cosine wave at 7 Hz. + In black, a sum of sines with frequencies of 3, 20 and 42 Hz. + In green, a square wave with a fundamental frequency of 0.5 Hz + (wavelength of 2 seconds). + * - |imgFftAction1| + - Amplitude spectra (zoom applied), with peaks visible at + the expected frequencies of 3, 7, 20 and 42 Hz for the sine and cosine + signals. In green, we see the complete series of peaks related to the square wave, + with a fundamental frequency at 0.5 Hz and harmonic frequencies at every + odd multiple of the fundamental. diff --git a/doc/source/modules/gui/plot/plottools.rst b/doc/source/modules/gui/plot/plottools.rst new file mode 100644 index 0000000..4cf8f88 --- /dev/null +++ b/doc/source/modules/gui/plot/plottools.rst @@ -0,0 +1,36 @@ +:mod:`PlotTools`: Tool widgets for PlotWidget +============================================= + +.. currentmodule:: silx.gui.plot.PlotTools + +.. automodule:: silx.gui.plot.PlotTools + +:class:`PositionInfo` class +--------------------------- + +.. autoclass:: PositionInfo + :show-inheritance: + :members: + +:class:`LimitsToolBar` class +---------------------------- + +.. autoclass:: LimitsToolBar + :show-inheritance: + :members: + + +.. currentmodule:: silx.gui.plot + +:mod:`ColorBar`: ColorBar Widget +================================ + +.. currentmodule:: silx.gui.plot.ColorBar + +.. automodule:: silx.gui.plot.ColorBar + +:class:`ColorBarWidget` class +----------------------------- + +.. autoclass:: ColorBarWidget + :members: diff --git a/doc/source/modules/gui/plot/plotwidget.rst b/doc/source/modules/gui/plot/plotwidget.rst new file mode 100644 index 0000000..df576fc --- /dev/null +++ b/doc/source/modules/gui/plot/plotwidget.rst @@ -0,0 +1,173 @@ + +.. currentmodule:: silx.gui.plot + +:mod:`PlotWidget`: Base class for plotting widgets +================================================== + +.. module:: silx.gui.plot.PlotWidget + +.. currentmodule:: silx.gui.plot.PlotWidget + +The :class:`PlotWidget` is a Qt widget providing the plot API initially +provided in `PyMca `_. +It is the basis of other plot widget, thus all plot widgets share the same API. + +For an introduction and examples of the plot API, see :doc:`getting_started`. + +Plot API +-------- + +.. currentmodule:: silx.gui.plot.Plot + +This is a choosen subset of the complete plot API, the full API is +documented in :class:`silx.gui.plot.Plot`. + +.. currentmodule:: silx.gui.plot.PlotWidget + +.. autoclass:: PlotWidget + :show-inheritance: + +Plot data +......... + +Those methods allow to add and update plotted data: + +.. automethod:: PlotWidget.addCurve +.. automethod:: PlotWidget.addImage +.. automethod:: PlotWidget.addScatter +.. automethod:: PlotWidget.addHistogram + +Plot markers +............ + +It is also possible to add point or line markers to the plot: + +.. automethod:: PlotWidget.addMarker +.. automethod:: PlotWidget.addXMarker +.. automethod:: PlotWidget.addYMarker + +Remove data from the plot +......................... + +.. automethod:: PlotWidget.clear +.. automethod:: PlotWidget.remove + +Title and labels +................ + +Those methods handle the text labels of the axes and the plot title: + +.. automethod:: PlotWidget.getGraphTitle +.. automethod:: PlotWidget.setGraphTitle +.. automethod:: PlotWidget.getGraphXLabel +.. automethod:: PlotWidget.setGraphXLabel +.. automethod:: PlotWidget.getGraphYLabel +.. automethod:: PlotWidget.setGraphYLabel + +Axes limits +........... + +Those methods change the range of data values displayed on each axis. + +.. automethod:: PlotWidget.getGraphXLimits +.. automethod:: PlotWidget.setGraphXLimits +.. automethod:: PlotWidget.getGraphYLimits +.. automethod:: PlotWidget.setGraphYLimits +.. automethod:: PlotWidget.setLimits + +Axes +.... + +The following methods handle the display properties of the axes: + +.. automethod:: PlotWidget.isXAxisLogarithmic +.. automethod:: PlotWidget.setXAxisLogarithmic +.. automethod:: PlotWidget.isYAxisLogarithmic +.. automethod:: PlotWidget.setYAxisLogarithmic + +.. automethod:: PlotWidget.isYAxisInverted +.. automethod:: PlotWidget.setYAxisInverted +.. automethod:: PlotWidget.isKeepDataAspectRatio +.. automethod:: PlotWidget.setKeepDataAspectRatio +.. automethod:: PlotWidget.getGraphGrid +.. automethod:: PlotWidget.setGraphGrid + +Reset zoom +.......... + +.. automethod:: PlotWidget.resetZoom + +Those methods change the behavior of :meth:`PlotWidget.resetZoom`. + +.. automethod:: PlotWidget.getDataMargins +.. automethod:: PlotWidget.setDataMargins +.. automethod:: PlotWidget.isXAxisAutoScale +.. automethod:: PlotWidget.setXAxisAutoScale +.. automethod:: PlotWidget.isYAxisAutoScale +.. automethod:: PlotWidget.setYAxisAutoScale + +Defaults +........ + +Those methods set-up default values for :meth:`PlotWidget.addCurve` and +:meth:`PlotWidget.addImage`: + +.. automethod:: PlotWidget.getDefaultColormap +.. automethod:: PlotWidget.setDefaultColormap +.. automethod:: PlotWidget.getSupportedColormaps +.. automethod:: PlotWidget.setDefaultPlotPoints +.. automethod:: PlotWidget.setDefaultPlotLines + +Interaction +........... + +Those methods allow to change the interaction mode (e.g., drawing mode) +of the plot and to toggle the use of a crosshair cursor: + +.. automethod:: PlotWidget.getInteractiveMode +.. automethod:: PlotWidget.setInteractiveMode + +.. automethod:: PlotWidget.getGraphCursor +.. automethod:: PlotWidget.setGraphCursor + +Misc. +..... + +.. automethod:: PlotWidget.saveGraph + +Signals +....... + +The :class:`PlotWidget` provides the following Qt signals: + +.. autoattribute:: PlotWidget.sigPlotSignal +.. autoattribute:: PlotWidget.sigSetYAxisInverted +.. autoattribute:: PlotWidget.sigSetXAxisLogarithmic +.. autoattribute:: PlotWidget.sigSetYAxisLogarithmic +.. autoattribute:: PlotWidget.sigSetXAxisAutoScale +.. autoattribute:: PlotWidget.sigSetYAxisAutoScale +.. autoattribute:: PlotWidget.sigSetKeepDataAspectRatio +.. autoattribute:: PlotWidget.sigSetGraphGrid +.. autoattribute:: PlotWidget.sigSetGraphCursor +.. autoattribute:: PlotWidget.sigSetPanWithArrowKeys +.. autoattribute:: PlotWidget.sigContentChanged +.. autoattribute:: PlotWidget.sigActiveCurveChanged +.. autoattribute:: PlotWidget.sigActiveImageChanged +.. autoattribute:: PlotWidget.sigInteractiveModeChanged + +.. Not documented: + addItem, removeItem, clearItems + isActiveCurveHandling, enableActiveCurveHandling, + getActiveCurveColor, setActiveCurveColor, + getActiveCurve, setActiveCurve, + isCurveHidden, hideCurve, + getActiveImage, setActiveImage, + getAllCurves, getCurve, getImage, getAllImages, + getScatter, getHistogram, + setDefaultPlotPoints, setDefaultPlotLines, + getWidgetHandle, notify, setCallback, graphCallback, + dataToPixel, pixelToData, getPlotBoundsInPixels, + setGraphCursorShape, pickMarker, moveMarker, pickImageOrCurve, moveImage, + onMousePress, onMouseMove, onMouseRelease, onMouseWheel, + isDrawModeEnabled, setDrawModeEnabled, getDrawMode, + isZoomModeEnabled, setZoomModeEnabled, diff --git a/doc/source/modules/gui/plot/plotwindow.rst b/doc/source/modules/gui/plot/plotwindow.rst new file mode 100644 index 0000000..1447403 --- /dev/null +++ b/doc/source/modules/gui/plot/plotwindow.rst @@ -0,0 +1,30 @@ + +.. currentmodule:: silx.gui.plot + +:mod:`PlotWindow`: Plot widget with toolbar +=========================================== + +.. automodule:: silx.gui.plot.PlotWindow + +.. currentmodule:: silx.gui.plot.PlotWindow + +:class:`PlotWindow` class +------------------------- + +.. autoclass:: PlotWindow + :show-inheritance: + :members: + +:class:`Plot1D`: Plot curves +---------------------------- + +.. autoclass:: Plot1D + :show-inheritance: + :members: + +:class:`Plot2D`: Plot images +---------------------------- + +.. autoclass:: Plot2D + :show-inheritance: + :members: diff --git a/doc/source/modules/gui/plot/profile.rst b/doc/source/modules/gui/plot/profile.rst new file mode 100644 index 0000000..56530f3 --- /dev/null +++ b/doc/source/modules/gui/plot/profile.rst @@ -0,0 +1,20 @@ +:mod:`Profile`: Toolbars with profile tools +=========================================== + +.. currentmodule:: silx.gui.plot.Profile + +.. automodule:: silx.gui.plot.Profile + +:class:`ProfileToolBar` class +----------------------------- + +.. autoclass:: ProfileToolBar + :show-inheritance: + :members: + +:class:`Profile3DToolBar` class +------------------------------- + +.. autoclass:: Profile3DToolBar + :show-inheritance: + :members: diff --git a/doc/source/modules/gui/plot/roi.rst b/doc/source/modules/gui/plot/roi.rst new file mode 100644 index 0000000..77b5c2a --- /dev/null +++ b/doc/source/modules/gui/plot/roi.rst @@ -0,0 +1,17 @@ +.. currentmodule:: silx.gui.plot + +:mod:`CurvesROIWidget`: ROI from curves +======================================= + +.. |roiWidgetImage| image:: img/roiwidget.png + :height: 400px + :align: middle + +You can access to the ROIWidget from a Plot window by : + +- using the tool button 'ROI' +- using the options button then by selecting region of interest. + +|roiWidgetImage| + +.. automodule:: silx.gui.plot.CurvesROIWidget diff --git a/doc/source/modules/gui/plot/stackview.rst b/doc/source/modules/gui/plot/stackview.rst new file mode 100644 index 0000000..7f2442a --- /dev/null +++ b/doc/source/modules/gui/plot/stackview.rst @@ -0,0 +1,24 @@ + +.. currentmodule:: silx.gui.plot + +:mod:`StackView`: Plot a stack of images +========================================= + +.. automodule:: silx.gui.plot.StackView + +.. currentmodule:: silx.gui.plot.StackView + +:class:`StackView` class +------------------------ + +.. autoclass:: StackView + :members: + :exclude-members: remove, setInteractiveMode, addItem + +:class:`StackViewMainWindow` class +---------------------------------- + +.. autoclass:: StackViewMainWindow + :show-inheritance: + :members: + diff --git a/doc/source/modules/gui/plot3d/actions.rst b/doc/source/modules/gui/plot3d/actions.rst new file mode 100644 index 0000000..a2fde68 --- /dev/null +++ b/doc/source/modules/gui/plot3d/actions.rst @@ -0,0 +1,10 @@ +Actions +======= + +:mod:`Plot3DActions` +-------------------- + +.. currentmodule:: silx.gui.plot3d.Plot3DActions + +.. automodule:: silx.gui.plot3d.Plot3DActions + :members: diff --git a/doc/source/modules/gui/plot3d/dev.rst b/doc/source/modules/gui/plot3d/dev.rst new file mode 100644 index 0000000..757240e --- /dev/null +++ b/doc/source/modules/gui/plot3d/dev.rst @@ -0,0 +1,38 @@ +Package structure +================= + +The :mod:`silx.gui.plot3d` package provides 3D visualisation widgets. +This package is structured as follows. + +.. currentmodule:: silx.gui.plot3d + +Widget-level API +---------------- + +Widgets are available as modules of the :mod:`silx.gui.plot3d` packages. + +The :mod:`.Plot3DWidget` module provides the OpenGL canvas where the scene is rendered. +The :mod:`.Plot3DWindow` module provides a :class:`QMainWindow` with a :class:`Plot3DWindow` as its central widget +and toolbars: :class:`ViewpointToolBar` and :class:`Plot3DToolBar`. +:class:`QAction` that can be associated with a :class:`Plot3DWidget` are defined in the :mod:`.Plot3DActions` module. +Those actions are used by the :class:`Plot3DToolBar` toolbar. + +The :mod:`.ScalarFieldView` module defines the :class:`ScalarFieldView` widget that displays iso-surfaces of a 3D scalar data set and the associated classes. +The :mod:`.SFViewParamTree` module defines a :class:`SFViewParamTree.TreeView` widget that can be attached to a :class:`ScalarFieldView` to control the display. + +OpenGL scene API +---------------- + +This API is NOT stable. +Widgets of :mod:`silx.gui.plot3d` are based on the following sub-packages: + +- :mod:`.scene`: Provides a hierarchical scene structure handling rendering and interaction. +- :mod:`.utils`: Miscellaneous supporting modules. +- :mod:`silx.gui._glutils`: Loads PyOpenGL and provides classes to handle OpenGL resources. + +.. toctree:: + :maxdepth: 2 + + scene.rst + utils.rst + glutils.rst diff --git a/doc/source/modules/gui/plot3d/glutils.rst b/doc/source/modules/gui/plot3d/glutils.rst new file mode 100644 index 0000000..2c36e83 --- /dev/null +++ b/doc/source/modules/gui/plot3d/glutils.rst @@ -0,0 +1,67 @@ +:mod:`_glutils` +=============== + +.. automodule:: silx.gui._glutils + + +:mod:`_glutils.gl` +------------------ + +.. automodule:: silx.gui._glutils.gl + :members: + +Utility functions +----------------- + +.. currentmodule:: silx.gui._glutils + +For OpenGL context management: + +.. autofunction:: getGLContext + +.. autofunction:: setGLContextGetter + +For type checking and conversion: + +.. autofunction:: sizeofGLType + +.. autofunction:: isSupportedGLType + +.. autofunction:: numpyToGLType + +:class:`Program` +---------------- + +.. autoclass:: Program + :members: + +:class:`Texture` +---------------- + +.. autoclass:: Texture + :members: + +:class:`FramebufferTexture` +--------------------------- + +.. autoclass:: FramebufferTexture + :members: + +Vertex Buffer +------------- + +.. autoclass:: VertexBuffer + :members: + +.. autoclass:: VertexBufferAttrib + :members: + +.. autofunction:: vertexBuffer + +:mod:`font` +----------- + +.. currentmodule:: silx.gui._glutils.font + +.. automodule:: silx.gui._glutils.font + :members: diff --git a/doc/source/modules/gui/plot3d/img/Plot3DWidget.png b/doc/source/modules/gui/plot3d/img/Plot3DWidget.png new file mode 100644 index 0000000..d39e4db Binary files /dev/null and b/doc/source/modules/gui/plot3d/img/Plot3DWidget.png differ diff --git a/doc/source/modules/gui/plot3d/img/Plot3DWindow.png b/doc/source/modules/gui/plot3d/img/Plot3DWindow.png new file mode 100644 index 0000000..0e562f5 Binary files /dev/null and b/doc/source/modules/gui/plot3d/img/Plot3DWindow.png differ diff --git a/doc/source/modules/gui/plot3d/img/SFViewParamTree.png b/doc/source/modules/gui/plot3d/img/SFViewParamTree.png new file mode 100644 index 0000000..1b44ed9 Binary files /dev/null and b/doc/source/modules/gui/plot3d/img/SFViewParamTree.png differ diff --git a/doc/source/modules/gui/plot3d/img/ScalarFieldView.png b/doc/source/modules/gui/plot3d/img/ScalarFieldView.png new file mode 100644 index 0000000..f40fdac Binary files /dev/null and b/doc/source/modules/gui/plot3d/img/ScalarFieldView.png differ diff --git a/doc/source/modules/gui/plot3d/index.rst b/doc/source/modules/gui/plot3d/index.rst new file mode 100644 index 0000000..8941403 --- /dev/null +++ b/doc/source/modules/gui/plot3d/index.rst @@ -0,0 +1,83 @@ + +.. currentmodule:: silx.gui + +:mod:`plot3d`: 3D Visualisation widgets +======================================= + +.. currentmodule:: silx.gui.plot3d + +.. automodule:: silx.gui.plot3d + +Widgets gallery +--------------- + +.. |imgPlot3DWidget| image:: img/Plot3DWidget.png + :height: 150px + :align: middle + +.. |imgPlot3DWindow| image:: img/Plot3DWindow.png + :height: 150px + :align: middle + +.. |imgScalarFieldView| image:: img/ScalarFieldView.png + :height: 150px + :align: middle + +.. |imgSFViewParamTree| image:: img/SFViewParamTree.png + :height: 150px + :align: middle + +.. list-table:: + :widths: 1 4 + :header-rows: 1 + + * - Widget + - Description + * - |imgScalarFieldView| + - :class:`ScalarFieldView` is a :class:`Plot3DWindow` dedicated to display 3D scalar field. + It can display iso-surfaces and an interactive cutting plane. + Sample code: :doc:`viewer3dvolume_example`. + * - |imgPlot3DWindow| + - :class:`Plot3DWindow` is a :class:`QMainWindow` with a :class:`Plot3DWidget` as central widget + and toolbars. + * - |imgPlot3DWidget| + - :class:`Plot3DWidget` is the base Qt widget providing an OpenGL 3D scene. + Other widgets are using this widget as the OpenGL scene canvas. + * - |imgSFViewParamTree| + - :class:`SFViewParamTree` is a :class:`QTreeView` widget that can be attached to a :class:`ScalarFieldView`. + It displays current parameters of the :class:`ScalarFieldView` and allows to modify it. + Sample code: :doc:`viewer3dvolume_example`. + +Public modules +-------------- + +The following sub-modules are available: + +.. toctree:: + :maxdepth: 2 + + plot3dwidget.rst + plot3dwindow.rst + scalarfieldview.rst + sfviewparamtree.rst + toolbars.rst + actions.rst + + +Sample code +----------- + +- :doc:`viewer3dvolume_example`: Sample code using :class:`ScalarFieldView` + +Internals +--------- + +.. toctree:: + :maxdepth: 2 + + dev.rst + +.. toctree:: + :hidden: + + viewer3dvolume_example.rst diff --git a/doc/source/modules/gui/plot3d/plot3dwidget.rst b/doc/source/modules/gui/plot3d/plot3dwidget.rst new file mode 100644 index 0000000..1b01eac --- /dev/null +++ b/doc/source/modules/gui/plot3d/plot3dwidget.rst @@ -0,0 +1,15 @@ +.. currentmodule:: silx.gui.plot3d + +:mod:`Plot3DWidget`: OpenGL scene widget +======================================== + +.. automodule:: silx.gui.plot3d.Plot3DWidget + +.. currentmodule:: silx.gui.plot3d.Plot3DWidget + +:class:`Plot3DWidget` +--------------------- + +.. autoclass:: Plot3DWidget + :show-inheritance: + :members: diff --git a/doc/source/modules/gui/plot3d/plot3dwindow.rst b/doc/source/modules/gui/plot3d/plot3dwindow.rst new file mode 100644 index 0000000..4b4264d --- /dev/null +++ b/doc/source/modules/gui/plot3d/plot3dwindow.rst @@ -0,0 +1,15 @@ +.. currentmodule:: silx.gui.plot3d + +:mod:`Plot3DWindow`: OpenGL scene and toolbar +============================================= + +.. automodule:: silx.gui.plot3d.Plot3DWindow + +.. currentmodule:: silx.gui.plot3d.Plot3DWindow + +:class:`Plot3DWindow` +--------------------- + +.. autoclass:: Plot3DWindow + :show-inheritance: + :members: diff --git a/doc/source/modules/gui/plot3d/scalarfieldview.rst b/doc/source/modules/gui/plot3d/scalarfieldview.rst new file mode 100644 index 0000000..763c18e --- /dev/null +++ b/doc/source/modules/gui/plot3d/scalarfieldview.rst @@ -0,0 +1,50 @@ +.. currentmodule:: silx.gui.plot3d + +:mod:`ScalarFieldView`: 3D volume scalar data viewer +==================================================== + +.. automodule:: silx.gui.plot3d.ScalarFieldView + +For sample code using ScalarFieldView, see :doc:`viewer3dvolume_example` + +.. currentmodule:: silx.gui.plot3d.ScalarFieldView + +:class:`ScalarFieldView` +------------------------ + +.. autoclass:: ScalarFieldView + :show-inheritance: + :members: + +Helper classes +-------------- + +Those classes are used by :class:`ScalarFieldView`. + +:class:`Colormap` ++++++++++++++++++ + +.. autoclass:: Colormap + :show-inheritance: + :members: + +:class:`CutPlane` ++++++++++++++++++ + +.. autoclass:: CutPlane + :show-inheritance: + :members: + +:class:`IsoSurface` ++++++++++++++++++++ + +.. autoclass:: Isosurface + :show-inheritance: + :members: + +:class:`SelectedRegion` ++++++++++++++++++++++++ + +.. autoclass:: SelectedRegion + :show-inheritance: + :members: diff --git a/doc/source/modules/gui/plot3d/scene.rst b/doc/source/modules/gui/plot3d/scene.rst new file mode 100644 index 0000000..4f6d9c4 --- /dev/null +++ b/doc/source/modules/gui/plot3d/scene.rst @@ -0,0 +1,84 @@ +:mod:`scene` +============ + +.. currentmodule:: silx.gui.plot3d.scene + +.. automodule:: silx.gui.plot3d.scene + +:mod:`axes`: Bounding Box with axes ticks and labels +---------------------------------------------------- + +.. automodule:: silx.gui.plot3d.scene.axes + :members: + +:mod:`camera`: Projection management classes +-------------------------------------------- + +.. automodule:: silx.gui.plot3d.scene.camera + :members: + +:mod:`core`: Base class of the scene nodes +------------------------------------------ + +.. automodule:: silx.gui.plot3d.scene.core + :members: + +:mod:`cutplane`: Cutting plane primitive +---------------------------------------- + +.. automodule:: silx.gui.plot3d.scene.cutplane + :members: + +:mod:`event`: Scene event system +-------------------------------- + +.. automodule:: silx.gui.plot3d.scene.event + :members: + +:mod:`function`: OpenGL shader functions +---------------------------------------- + +.. automodule:: silx.gui.plot3d.scene.function + :members: + +:mod:`interaction`: User interaction implementation +--------------------------------------------------- + +.. automodule:: silx.gui.plot3d.scene.interaction + :members: + +:mod:`primitives`: Base rendering primitives +-------------------------------------------- + +.. automodule:: silx.gui.plot3d.scene.primitives + :members: + +:mod:`text`: Text field rendering primitives +-------------------------------------------- + +.. automodule:: silx.gui.plot3d.scene.text + :members: + +:mod:`transform`: Transformation matrix system +---------------------------------------------- + +.. automodule:: silx.gui.plot3d.scene.transform + :members: + +:mod:`utils`: Miscellaneous +--------------------------- + +.. automodule:: silx.gui.plot3d.scene.utils + :members: + +:mod:`viewport`: Root of a scene tree +------------------------------------- + +.. automodule:: silx.gui.plot3d.scene.viewport + :members: + +:mod:`window`: On-screen window +------------------------------- + +.. automodule:: silx.gui.plot3d.scene.window + :members: diff --git a/doc/source/modules/gui/plot3d/sfviewparamtree.rst b/doc/source/modules/gui/plot3d/sfviewparamtree.rst new file mode 100644 index 0000000..bfb4052 --- /dev/null +++ b/doc/source/modules/gui/plot3d/sfviewparamtree.rst @@ -0,0 +1,13 @@ +:mod:`SFViewParamTree`: :class:`ScalarFieldView` parameters widget +================================================================== + +.. currentmodule:: silx.gui.plot3d.SFViewParamTree + +.. automodule:: silx.gui.plot3d.SFViewParamTree + +:class:`TreeView` +----------------- + +.. autoclass:: TreeView + :show-inheritance: + :members: diff --git a/doc/source/modules/gui/plot3d/toolbars.rst b/doc/source/modules/gui/plot3d/toolbars.rst new file mode 100644 index 0000000..df4b4ef --- /dev/null +++ b/doc/source/modules/gui/plot3d/toolbars.rst @@ -0,0 +1,29 @@ +Toolbars +======== + + +:mod:`ViewpointToolbar` +----------------------- + +.. currentmodule:: silx.gui.plot3d.ViewpointToolBar + +.. automodule:: silx.gui.plot3d.ViewpointToolBar + +.. autoclass:: ViewpointActionGroup + :show-inheritance: + :members: + +.. autoclass:: ViewpointToolBar + :show-inheritance: + :members: + +:mod:`Plot3DToolbar` +-------------------- + +.. currentmodule:: silx.gui.plot3d.Plot3DToolBar + +.. automodule:: silx.gui.plot3d.Plot3DToolBar + +.. autoclass:: Plot3DToolBar + :show-inheritance: + :members: diff --git a/doc/source/modules/gui/plot3d/utils.rst b/doc/source/modules/gui/plot3d/utils.rst new file mode 100644 index 0000000..fcd5426 --- /dev/null +++ b/doc/source/modules/gui/plot3d/utils.rst @@ -0,0 +1,12 @@ +:mod:`utils` +============ + +.. currentmodule:: silx.gui.plot3d.utils + +.. automodule:: silx.gui.plot3d.utils + +:mod:`mng` +---------- + +.. automodule:: silx.gui.plot3d.utils.mng + :members: diff --git a/doc/source/modules/gui/plot3d/viewer3dvolume_example.rst b/doc/source/modules/gui/plot3d/viewer3dvolume_example.rst new file mode 100644 index 0000000..5368e05 --- /dev/null +++ b/doc/source/modules/gui/plot3d/viewer3dvolume_example.rst @@ -0,0 +1,7 @@ +viewer3DVolume.py +================= + +Sample code demonstrating :mod:`silx.gui.plot3d.ScalarFieldView` widget: + +.. literalinclude:: ../../../../../examples/viewer3DVolume.py + :lines: 38- \ No newline at end of file diff --git a/doc/source/modules/gui/qt.rst b/doc/source/modules/gui/qt.rst new file mode 100644 index 0000000..bcdad13 --- /dev/null +++ b/doc/source/modules/gui/qt.rst @@ -0,0 +1,8 @@ + +.. currentmodule:: silx.gui + +:mod:`qt`: Qt bindings +---------------------- + +.. automodule:: silx.gui.qt + :members: BINDING diff --git a/doc/source/modules/gui/update_icons_rst.py b/doc/source/modules/gui/update_icons_rst.py new file mode 100644 index 0000000..3f6565a --- /dev/null +++ b/doc/source/modules/gui/update_icons_rst.py @@ -0,0 +1,90 @@ +# coding: utf-8 +# /*########################################################################## +# +# Copyright (c) 2016 European Synchrotron Radiation Facility +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +# +# ###########################################################################*/ +"""Script to update icons.rst file according to icons available in resources. +""" + +__authors__ = ["Thomas Vincent"] +__license__ = "MIT" +__date__ = "30/06/2016" + + +import os +import glob + + +ICONS_RST_FILENAME = os.path.join(os.path.dirname(__file__), 'icons.rst') + + +ICONS_DIR = os.path.join( + os.path.dirname(__file__), + '..', '..', '..', '..', 'silx', 'resources', 'gui', 'icons', '*.png') + + +ICONS_RST_HEADER = """ +.. AUTOMATICALLY GENERATED FILE DO NOT EDIT + Use %s script instead + +.. currentmodule:: silx.gui + +:mod:`icons`: Set of icons +-------------------------- + +.. automodule:: silx.gui.icons + :members: + +Available icons ++++++++++++++++ + +.. list-table:: + :widths: 1 4 + :header-rows: 1 + + * - Icon + - Name +""" % os.path.basename(__file__) + + +def main(): + """Write icons.rst file""" + icons = glob.glob(ICONS_DIR) + icons = [os.path.relpath(f, os.path.dirname(__file__)) for f in icons] + icons = sorted(icons) + + icons_table = '\n'.join( + ' * - |%s|\n - %s' % (os.path.basename(f)[:-4], + os.path.basename(f)[:-4]) for f in icons) + + icon_definitions = '\n'.join( + '.. |%s| image:: %s' % (os.path.basename(f)[:-4], f) for f in icons) + + content = ICONS_RST_HEADER + icons_table + '\n\n' + icon_definitions + '\n' + + # Write to file + with open(ICONS_RST_FILENAME, 'w') as f: + f.write(content) + + +if __name__ == '__main__': + main() diff --git a/doc/source/modules/gui/widgets/framebrowser.rst b/doc/source/modules/gui/widgets/framebrowser.rst new file mode 100644 index 0000000..5ea0918 --- /dev/null +++ b/doc/source/modules/gui/widgets/framebrowser.rst @@ -0,0 +1,19 @@ + +.. currentmodule:: silx.gui.widgets + +:mod:`FrameBrowser` +------------------- + +.. automodule:: silx.gui.widgets.FrameBrowser + +API +*** + +.. autoclass:: silx.gui.widgets.FrameBrowser.HorizontalSliderWithBrowser + :members: + + +.. autoclass:: silx.gui.widgets.FrameBrowser.FrameBrowser + :members: + + diff --git a/doc/source/modules/gui/widgets/index.rst b/doc/source/modules/gui/widgets/index.rst new file mode 100644 index 0000000..2284f22 --- /dev/null +++ b/doc/source/modules/gui/widgets/index.rst @@ -0,0 +1,19 @@ + +.. currentmodule:: silx.gui + +:mod:`widgets`: Simple widgets +------------------------------ + +.. automodule:: silx.gui.widgets + + +Public modules: + +.. toctree:: + :maxdepth: 2 + + framebrowser.rst + periodictable.rst + tablewidget.rst + threadpoolpushbutton.rst + waitingpushbutton.rst diff --git a/doc/source/modules/gui/widgets/periodictable.rst b/doc/source/modules/gui/widgets/periodictable.rst new file mode 100644 index 0000000..dead3d9 --- /dev/null +++ b/doc/source/modules/gui/widgets/periodictable.rst @@ -0,0 +1,37 @@ + +.. currentmodule:: silx.gui.widgets + +:mod:`PeriodicTable`: Atomic elements widgets +---------------------------------------------- + +.. automodule:: silx.gui.widgets.PeriodicTable + +Widgets ++++++++ + +.. autoclass:: silx.gui.widgets.PeriodicTable.PeriodicTable + :members: + :exclude-members: elementEnter, elementLeave, elementClicked, elementToggle + :show-inheritance: + + +.. autoclass:: silx.gui.widgets.PeriodicTable.PeriodicList + :members: + :show-inheritance: + +.. autoclass:: silx.gui.widgets.PeriodicTable.PeriodicCombo + :members: + :show-inheritance: + + +Data model +++++++++++ + +.. autoclass:: silx.gui.widgets.PeriodicTable.PeriodicTableItem + :members: + + +.. autoclass:: silx.gui.widgets.PeriodicTable.ColoredPeriodicTableItem + :members: + :show-inheritance: + diff --git a/doc/source/modules/gui/widgets/tablewidget.rst b/doc/source/modules/gui/widgets/tablewidget.rst new file mode 100644 index 0000000..1eb5695 --- /dev/null +++ b/doc/source/modules/gui/widgets/tablewidget.rst @@ -0,0 +1,42 @@ + +.. currentmodule:: silx.gui.widgets + +:mod:`TableWidget`: Table widget +-------------------------------- + +.. automodule:: silx.gui.widgets.TableWidget + + +Widget +++++++ + +.. autoclass:: silx.gui.widgets.TableWidget.TableWidget + :members: + :show-inheritance: + + +View +++++ + +.. autoclass:: silx.gui.widgets.TableWidget.TableView + :members: + :show-inheritance: + + +Actions ++++++++ + +.. autoclass:: silx.gui.widgets.TableWidget.CopySelectedCellsAction + :show-inheritance: + +.. autoclass:: silx.gui.widgets.TableWidget.CopyAllCellsAction + :show-inheritance: + +.. autoclass:: silx.gui.widgets.TableWidget.CutSelectedCellsAction + :show-inheritance: + +.. autoclass:: silx.gui.widgets.TableWidget.CutAllCellsAction + :show-inheritance: + +.. autoclass:: silx.gui.widgets.TableWidget.PasteCellsAction + :show-inheritance: diff --git a/doc/source/modules/gui/widgets/threadpoolpushbutton.rst b/doc/source/modules/gui/widgets/threadpoolpushbutton.rst new file mode 100644 index 0000000..cd98ac4 --- /dev/null +++ b/doc/source/modules/gui/widgets/threadpoolpushbutton.rst @@ -0,0 +1,14 @@ + +.. currentmodule:: silx.gui.widgets + +:mod:`ThreadPoolPushButton`: Button to execute a threaded task +-------------------------------------------------------------- + +.. automodule:: silx.gui.widgets.ThreadPoolPushButton + + +.. autoclass:: silx.gui.widgets.ThreadPoolPushButton.ThreadPoolPushButton + :members: + + + diff --git a/doc/source/modules/gui/widgets/waitingpushbutton.rst b/doc/source/modules/gui/widgets/waitingpushbutton.rst new file mode 100644 index 0000000..310ea80 --- /dev/null +++ b/doc/source/modules/gui/widgets/waitingpushbutton.rst @@ -0,0 +1,13 @@ + +.. currentmodule:: silx.gui.widgets + +:mod:`WaitingPushButton`: Button with waiting status +---------------------------------------------------- + +.. automodule:: silx.gui.widgets.WaitingPushButton + +.. autoclass:: silx.gui.widgets.WaitingPushButton.WaitingPushButton + :members: + + + diff --git a/doc/source/modules/image/bilinear.rst b/doc/source/modules/image/bilinear.rst new file mode 100644 index 0000000..e155751 --- /dev/null +++ b/doc/source/modules/image/bilinear.rst @@ -0,0 +1,9 @@ + +.. currentmodule:: silx.image + +:mod:`bilinear`: Bilinear interpolator +--------------------------------------- + +.. automodule:: silx.image.bilinear + :members: + :special-members: __call__ diff --git a/doc/source/modules/image/index.rst b/doc/source/modules/image/index.rst new file mode 100644 index 0000000..abdeb64 --- /dev/null +++ b/doc/source/modules/image/index.rst @@ -0,0 +1,13 @@ + +.. py:module:: silx.image + +:mod:`silx.image`: +================== + +.. toctree:: + :maxdepth: 1 + + bilinear.rst + medianfilter.rst + shapes.rst + sift.rst diff --git a/doc/source/modules/image/medianfilter.rst b/doc/source/modules/image/medianfilter.rst new file mode 100644 index 0000000..412f8bb --- /dev/null +++ b/doc/source/modules/image/medianfilter.rst @@ -0,0 +1,7 @@ + +.. currentmodule:: silx.image.medianfilter + +:mod:`medianfilter`: Median filter +---------------------------------- + +.. autofunction:: silx.image.medianfilter.medfilt2d diff --git a/doc/source/modules/image/shapes.rst b/doc/source/modules/image/shapes.rst new file mode 100644 index 0000000..a20b0cd --- /dev/null +++ b/doc/source/modules/image/shapes.rst @@ -0,0 +1,8 @@ + +.. currentmodule:: silx.image + +:mod:`shapes`: 2D shapes drawing +--------------------------------- + +.. automodule:: silx.image.shapes + :members: circle_fill, draw_line, polygon_fill_mask, Polygon diff --git a/doc/source/modules/image/sift.rst b/doc/source/modules/image/sift.rst new file mode 100644 index 0000000..55a4752 --- /dev/null +++ b/doc/source/modules/image/sift.rst @@ -0,0 +1,8 @@ + +.. currentmodule:: silx.image + +:mod:`sift`: 2D image alignment +--------------------------------- + +.. automodule:: silx.image.sift + :members: SiftPlan, MatchPlan, LinearAlign diff --git a/doc/source/modules/index.rst b/doc/source/modules/index.rst new file mode 100644 index 0000000..b9a4753 --- /dev/null +++ b/doc/source/modules/index.rst @@ -0,0 +1,14 @@ +API Reference +============= + +.. toctree:: + :maxdepth: 2 + + gui/index.rst + io/index.rst + image/index.rst + math/index.rst + resources.rst + utils/index.rst + test/index.rst + diff --git a/doc/source/modules/io/configdict.rst b/doc/source/modules/io/configdict.rst new file mode 100644 index 0000000..bc0cdb7 --- /dev/null +++ b/doc/source/modules/io/configdict.rst @@ -0,0 +1,8 @@ + +.. currentmodule:: silx.io + +:mod:`configdict`: Configuration files I/O +------------------------------------------- + +.. automodule:: silx.io.configdict + :members: diff --git a/doc/source/modules/io/dictdump.rst b/doc/source/modules/io/dictdump.rst new file mode 100644 index 0000000..1778d78 --- /dev/null +++ b/doc/source/modules/io/dictdump.rst @@ -0,0 +1,8 @@ + +.. currentmodule:: silx.io + +:mod:`dictdump`: Dumping and loading dictionaries +-------------------------------------------------- + +.. automodule:: silx.io.dictdump + :members: diff --git a/doc/source/modules/io/index.rst b/doc/source/modules/io/index.rst new file mode 100644 index 0000000..1538a74 --- /dev/null +++ b/doc/source/modules/io/index.rst @@ -0,0 +1,25 @@ + +.. py:module:: silx.io + +:mod:`silx.io`: Input-output +============================ + + +.. toctree:: + :maxdepth: 1 + + configdict.rst + dictdump.rst + nxdata.rst + octaveh5.rst + specfile.rst + specfilewrapper.rst + spech5.rst + spectoh5.rst + utils.rst + +Top-level functions +------------------- + +.. autofunction:: silx.io.open +.. autofunction:: silx.io.save1D diff --git a/doc/source/modules/io/nxdata.rst b/doc/source/modules/io/nxdata.rst new file mode 100644 index 0000000..7940270 --- /dev/null +++ b/doc/source/modules/io/nxdata.rst @@ -0,0 +1,8 @@ + +.. currentmodule:: silx.io + +:mod:`nxdata`: NXdata group parsing +------------------------------------ + +.. automodule:: silx.io.nxdata + :members: diff --git a/doc/source/modules/io/octaveh5.rst b/doc/source/modules/io/octaveh5.rst new file mode 100644 index 0000000..982f346 --- /dev/null +++ b/doc/source/modules/io/octaveh5.rst @@ -0,0 +1,10 @@ + +.. currentmodule:: silx.io + +:mod:`octaveh5`: Octave HDF5 compatibility +------------------------------------------- + +.. automodule:: silx.io.octaveh5 + :members: + :show-inheritance: + :undoc-members: diff --git a/doc/source/modules/io/specfile.rst b/doc/source/modules/io/specfile.rst new file mode 100644 index 0000000..a937ca8 --- /dev/null +++ b/doc/source/modules/io/specfile.rst @@ -0,0 +1,83 @@ + +.. currentmodule:: silx.io + +:mod:`specfile`: Reading SpecFile +---------------------------------- + +.. automodule:: silx.io.specfile + :members: + :undoc-members: + +.. autoclass:: silx.io.specfile.SpecFile + :members: + :undoc-members: + + .. automethod:: __len__ + + .. automethod:: __iter__ + + .. automethod:: __getitem__ + +.. autoclass:: silx.io.specfile.Scan + :members: + :undoc-members: + +.. autoclass:: silx.io.specfile.MCA + :members: + :undoc-members: + + .. automethod:: __len__ + + .. automethod:: __iter__ + + .. automethod:: __getitem__ + +.. autoclass:: silx.io.specfile.SfError + +.. autoclass:: silx.io.specfile.SfErrMemoryAlloc + :show-inheritance: + +.. autoclass:: silx.io.specfile.SfErrFileOpen + :show-inheritance: + +.. autoclass:: silx.io.specfile.SfErrFileClose + :show-inheritance: + +.. autoclass:: silx.io.specfile.SfErrFileRead + :show-inheritance: + +.. autoclass:: silx.io.specfile.SfErrFileWrite + :show-inheritance: + +.. autoclass:: silx.io.specfile.SfErrLineNotFound + :show-inheritance: + +.. autoclass:: silx.io.specfile.SfErrScanNotFound + :show-inheritance: + +.. autoclass:: silx.io.specfile.SfErrHeaderNotFound + :show-inheritance: + +.. autoclass:: silx.io.specfile.SfErrLabelNotFound + :show-inheritance: + +.. autoclass:: silx.io.specfile.SfErrMotorNotFound + :show-inheritance: + +.. autoclass:: silx.io.specfile.SfErrPositionNotFound + :show-inheritance: + +.. autoclass:: silx.io.specfile.SfErrLineEmpty + :show-inheritance: + +.. autoclass:: silx.io.specfile.SfErrUserNotFound + :show-inheritance: + +.. autoclass:: silx.io.specfile.SfErrColNotFound + :show-inheritance: + +.. autoclass:: silx.io.specfile.SfErrMcaNotFound + :show-inheritance: + +.. autoclass:: silx.io.specfile.SfNoMcaError + :show-inheritance: diff --git a/doc/source/modules/io/specfilewrapper.rst b/doc/source/modules/io/specfilewrapper.rst new file mode 100644 index 0000000..3cd8915 --- /dev/null +++ b/doc/source/modules/io/specfilewrapper.rst @@ -0,0 +1,12 @@ + +.. currentmodule:: silx.io + +:mod:`specfilewrapper`: Reading SpecFile (old API) +--------------------------------------------------- + +.. automodule:: silx.io.specfilewrapper + :members: + :show-inheritance: + :undoc-members: + :special-members: __getitem__ + diff --git a/doc/source/modules/io/spech5.rst b/doc/source/modules/io/spech5.rst new file mode 100644 index 0000000..143d3bb --- /dev/null +++ b/doc/source/modules/io/spech5.rst @@ -0,0 +1,11 @@ + +.. currentmodule:: silx.io + +:mod:`spech5`: h5py-like API to SpecFile +----------------------------------------- + +.. automodule:: silx.io.spech5 + :members: + :show-inheritance: + :undoc-members: + :special-members: __getitem__, __len__, __contains__ diff --git a/doc/source/modules/io/spectoh5.rst b/doc/source/modules/io/spectoh5.rst new file mode 100644 index 0000000..05fc768 --- /dev/null +++ b/doc/source/modules/io/spectoh5.rst @@ -0,0 +1,8 @@ + +.. currentmodule:: silx.io + +:mod:`spectoh5`: SpecFile to HDF5 conversion +--------------------------------------------- + +.. automodule:: silx.io.spectoh5 + :members: write_spec_to_h5, convert diff --git a/doc/source/modules/io/utils.rst b/doc/source/modules/io/utils.rst new file mode 100644 index 0000000..f243bcb --- /dev/null +++ b/doc/source/modules/io/utils.rst @@ -0,0 +1,8 @@ + +.. currentmodule:: silx.io + +:mod:`utils`: I/O utilities +----------------------------- + +.. automodule:: silx.io.utils + :members: diff --git a/doc/source/modules/math/combo.rst b/doc/source/modules/math/combo.rst new file mode 100644 index 0000000..4d1b5c6 --- /dev/null +++ b/doc/source/modules/math/combo.rst @@ -0,0 +1,8 @@ +.. currentmodule:: silx.math + +:mod:`silx.math.combo`: Statistics combo functions +-------------------------------------------------- + +.. automodule:: silx.math.combo + +.. autofunction:: min_max diff --git a/doc/source/modules/math/fit/bgtheories.rst b/doc/source/modules/math/fit/bgtheories.rst new file mode 100644 index 0000000..5c6994a --- /dev/null +++ b/doc/source/modules/math/fit/bgtheories.rst @@ -0,0 +1,10 @@ + +.. currentmodule:: silx.math.fit + +See :mod:`fittheories` and :mod:`fittheory` for additional information. + +:mod:`bgtheories`: Background theories for :mod:`fitmanager` +------------------------------------------------------------ + +.. automodule:: silx.math.fit.bgtheories + :members: diff --git a/doc/source/modules/math/fit/filters.rst b/doc/source/modules/math/fit/filters.rst new file mode 100644 index 0000000..09f7145 --- /dev/null +++ b/doc/source/modules/math/fit/filters.rst @@ -0,0 +1,18 @@ + +.. currentmodule:: silx.math.fit + +Smoothing and background filters +-------------------------------- + +.. automodule:: silx.math.fit.filters + +.. autofunction:: silx.math.fit.smooth1d +.. autofunction:: silx.math.fit.smooth2d +.. autofunction:: silx.math.fit.smooth3d +.. autofunction:: silx.math.fit.savitsky_golay +.. autofunction:: silx.math.fit.snip1d +.. autofunction:: silx.math.fit.snip2d +.. autofunction:: silx.math.fit.snip3d +.. autofunction:: silx.math.fit.strip + + diff --git a/doc/source/modules/math/fit/fitmanager.rst b/doc/source/modules/math/fit/fitmanager.rst new file mode 100644 index 0000000..b8a9446 --- /dev/null +++ b/doc/source/modules/math/fit/fitmanager.rst @@ -0,0 +1,18 @@ + +.. currentmodule:: silx.math.fit + +:mod:`fitmanager`: Fit functions manager +---------------------------------------- + +.. automodule:: silx.math.fit.fitmanager + +For a tutorial on how to use :class:`FitManager`, see :ref:`fitmanager-tutorial`. + +API +... + +.. autoclass:: silx.math.fit.fitmanager.FitManager + :members: addbackground, addtheory, configure, disableweight, estimate, fit, fitconfig, + fit_results, gendata, enableweight, loadtheories, setdata, setbackground, + settheory, runfit + :special-members: __init__ diff --git a/doc/source/modules/math/fit/fittheories.rst b/doc/source/modules/math/fit/fittheories.rst new file mode 100644 index 0000000..4a0b6bc --- /dev/null +++ b/doc/source/modules/math/fit/fittheories.rst @@ -0,0 +1,8 @@ + +.. currentmodule:: silx.math.fit + +:mod:`fittheories`: Fit theories for :mod:`fitmanager` +-------------------------------------------------------- + +.. automodule:: silx.math.fit.fittheories + :members: diff --git a/doc/source/modules/math/fit/fittheory.rst b/doc/source/modules/math/fit/fittheory.rst new file mode 100644 index 0000000..ab29d17 --- /dev/null +++ b/doc/source/modules/math/fit/fittheory.rst @@ -0,0 +1,8 @@ + +.. currentmodule:: silx.math.fit + +:mod:`fittheory`: Fit theory definition +--------------------------------------- + +.. automodule:: silx.math.fit.fittheory + :members: diff --git a/doc/source/modules/math/fit/functions.rst b/doc/source/modules/math/fit/functions.rst new file mode 100644 index 0000000..f354964 --- /dev/null +++ b/doc/source/modules/math/fit/functions.rst @@ -0,0 +1,26 @@ + +.. currentmodule:: silx.math.fit + +Fit functions +------------- + +.. automodule:: silx.math.fit.functions + +.. autofunction:: silx.math.fit.atan_stepup +.. autofunction:: silx.math.fit.periodic_gauss +.. autofunction:: silx.math.fit.sum_agauss +.. autofunction:: silx.math.fit.sum_ahypermet +.. autofunction:: silx.math.fit.sum_alorentz +.. autofunction:: silx.math.fit.sum_apvoigt +.. autofunction:: silx.math.fit.sum_fastagauss +.. autofunction:: silx.math.fit.sum_fastahypermet +.. autofunction:: silx.math.fit.sum_gauss +.. autofunction:: silx.math.fit.sum_lorentz +.. autofunction:: silx.math.fit.sum_pvoigt +.. autofunction:: silx.math.fit.sum_slit +.. autofunction:: silx.math.fit.sum_splitgauss +.. autofunction:: silx.math.fit.sum_splitlorentz +.. autofunction:: silx.math.fit.sum_splitpvoigt +.. autofunction:: silx.math.fit.sum_stepdown +.. autofunction:: silx.math.fit.sum_stepup + diff --git a/doc/source/modules/math/fit/index.rst b/doc/source/modules/math/fit/index.rst new file mode 100644 index 0000000..958e339 --- /dev/null +++ b/doc/source/modules/math/fit/index.rst @@ -0,0 +1,25 @@ + +.. currentmodule:: silx.math +.. py:module:: silx.math.fit + +:mod:`fit`: Fitting tools +========================== + +.. toctree:: + :maxdepth: 1 + + leastsq.rst + peaksearch.rst + functions.rst + filters.rst + fitmanager.rst + fittheory.rst + fittheories.rst + bgtheories.rst + + +For a graphical fit widget, see :mod:`silx.gui.fit.FitWidget`. + +For a tutorial on using the various fit related modules, see :ref:`fit-tutorial` . + + diff --git a/doc/source/modules/math/fit/leastsq.rst b/doc/source/modules/math/fit/leastsq.rst new file mode 100644 index 0000000..35c105f --- /dev/null +++ b/doc/source/modules/math/fit/leastsq.rst @@ -0,0 +1,16 @@ + +.. currentmodule:: silx.math.fit + +:mod:`leastsq`: Levenberg Marquardt with constraints +----------------------------------------------------- + +.. automodule:: silx.math.fit.leastsq + :noindex: + +For a tutorial on how to use :func:`leastsq`, see :ref:`leastsq-tutorial`. + +Functions ++++++++++ + +.. autofunction:: silx.math.fit.leastsq +.. autofunction:: silx.math.fit.chisq_alpha_beta diff --git a/doc/source/modules/math/fit/peaksearch.rst b/doc/source/modules/math/fit/peaksearch.rst new file mode 100644 index 0000000..b1c70eb --- /dev/null +++ b/doc/source/modules/math/fit/peaksearch.rst @@ -0,0 +1,10 @@ + +.. currentmodule:: silx.math.fit + +Peak search function +-------------------- + +.. automodule:: silx.math.fit.peaks + +.. autofunction:: silx.math.fit.peaks.peak_search +.. autofunction:: silx.math.fit.peaks.guess_fwhm diff --git a/doc/source/modules/math/histogram.rst b/doc/source/modules/math/histogram.rst new file mode 100644 index 0000000..06a9fed --- /dev/null +++ b/doc/source/modules/math/histogram.rst @@ -0,0 +1,21 @@ + +.. currentmodule:: silx.math + +:mod:`histogram`: Multidimensional histograms +---------------------------------------------- + +.. automodule:: silx.math.histogram + + +Classes ++++++++ + +.. autoclass:: silx.math.histogram.Histogramnd + :members: + :undoc-members: + :special-members: __init__, __getitem__ + +.. autoclass:: silx.math.histogram.HistogramndLut + :members: + :undoc-members: + :special-members: __init__ diff --git a/doc/source/modules/math/index.rst b/doc/source/modules/math/index.rst new file mode 100644 index 0000000..ece49dd --- /dev/null +++ b/doc/source/modules/math/index.rst @@ -0,0 +1,13 @@ + +.. py:module:: silx.math + +:mod:`silx.math`: +================== + +.. toctree:: + :maxdepth: 1 + + fit/index.rst + histogram.rst + medianfilter.rst + combo.rst diff --git a/doc/source/modules/math/medianfilter.rst b/doc/source/modules/math/medianfilter.rst new file mode 100644 index 0000000..bb8903c --- /dev/null +++ b/doc/source/modules/math/medianfilter.rst @@ -0,0 +1,11 @@ + +.. currentmodule:: silx.math.medianfilter + +:mod:`medianfilter`: Median filter +---------------------------------- + +.. autofunction:: silx.math.medianfilter.medfilt + +.. autofunction:: silx.math.medianfilter.medfilt1d + +.. autofunction:: silx.math.medianfilter.medfilt2d diff --git a/doc/source/modules/resources.rst b/doc/source/modules/resources.rst new file mode 100644 index 0000000..03e419a --- /dev/null +++ b/doc/source/modules/resources.rst @@ -0,0 +1,7 @@ +.. currentmodule:: silx + +:mod:`silx.resources`: Project resources access +=============================================== + +.. automodule:: silx.resources + :members: diff --git a/doc/source/modules/test/index.rst b/doc/source/modules/test/index.rst new file mode 100644 index 0000000..f9d8ec0 --- /dev/null +++ b/doc/source/modules/test/index.rst @@ -0,0 +1,20 @@ +:mod:`silx.test`: +================= + +:mod:`silx.test` +---------------- + +.. automodule:: silx.test + :members: + +:mod:`silx.test.utils` +---------------------- + +.. automodule:: silx.test.utils + :members: + +:mod:`silx.gui.test.utils` +-------------------------- + +.. automodule:: silx.gui.test.utils + :members: diff --git a/doc/source/modules/utils/array_like.rst b/doc/source/modules/utils/array_like.rst new file mode 100644 index 0000000..4b477ea --- /dev/null +++ b/doc/source/modules/utils/array_like.rst @@ -0,0 +1,7 @@ +.. currentmodule:: silx.utils + +:mod:`array_like` +----------------- + +.. automodule:: silx.utils.array_like + :members: diff --git a/doc/source/modules/utils/decorators.rst b/doc/source/modules/utils/decorators.rst new file mode 100644 index 0000000..1da0f44 --- /dev/null +++ b/doc/source/modules/utils/decorators.rst @@ -0,0 +1,7 @@ +.. currentmodule:: silx.utils + +:mod:`decorators` +------------------ + +.. automodule:: silx.utils.decorators + :members: diff --git a/doc/source/modules/utils/html.rst b/doc/source/modules/utils/html.rst new file mode 100644 index 0000000..1e590f4 --- /dev/null +++ b/doc/source/modules/utils/html.rst @@ -0,0 +1,7 @@ +.. currentmodule:: silx.utils + +:mod:`html` +----------- + +.. automodule:: silx.utils.html + :members: diff --git a/doc/source/modules/utils/index.rst b/doc/source/modules/utils/index.rst new file mode 100644 index 0000000..4eac097 --- /dev/null +++ b/doc/source/modules/utils/index.rst @@ -0,0 +1,11 @@ +:mod:`silx.utils`: +================== + +.. toctree:: + :maxdepth: 2 + + array_like.rst + decorators.rst + html.rst + weakref.rst + diff --git a/doc/source/modules/utils/weakref.rst b/doc/source/modules/utils/weakref.rst new file mode 100644 index 0000000..8d5a77a --- /dev/null +++ b/doc/source/modules/utils/weakref.rst @@ -0,0 +1,7 @@ +.. currentmodule:: silx.utils + +:mod:`weakref` +--------------- + +.. automodule:: silx.utils.weakref + :members: diff --git a/doc/source/overview.rst b/doc/source/overview.rst new file mode 100644 index 0000000..f6def11 --- /dev/null +++ b/doc/source/overview.rst @@ -0,0 +1,33 @@ +Overview +======== + +Releases +-------- + +Source code, pre-built binaries (aka Python wheels) for Windows and Mac OS X and Debian packages of releases are made available at the following places: + +- `Wheels and source code on PyPi `_ +- `Debian 8 packages `_ +- `Documentation on PythonHosted `_ +- :doc:`changelog` + +Nightly builds +-------------- + +Debian 8 packages and documentation are automatically generated from the tip of the project's repository on a daily basis: + +- `Debian 8 packages `_ +- `Documentation `_ + +Project +------- + +- `Homepage `_ +- `Source repository `_ +- `Issue tracker `_ +- Mailing list: silx@esrf.fr (`Archive `_) +- Continuous integration + + - Linux and MacOS X: `Travis `_ + - Windows: `AppVeyor `_ + diff --git a/doc/source/tutorials.rst b/doc/source/tutorials.rst new file mode 100644 index 0000000..8ea536b --- /dev/null +++ b/doc/source/tutorials.rst @@ -0,0 +1,17 @@ +Tutorials +========= + +Tutorials and cookbooks: + +.. toctree:: + :maxdepth: 1 + + modules/gui/plot/getting_started.rst + modules/gui/plot/plotactions_examples.rst + modules/gui/designer.rst + Tutorials/Sift/sift.rst + Tutorials/specfile_to_hdf5.rst + modules/gui/hdf5/getting_started.rst + Tutorials/fit.rst + Tutorials/fitconfig.rst + Tutorials/array_widget.rst diff --git a/doc/source/virtualenv.rst b/doc/source/virtualenv.rst new file mode 100644 index 0000000..db8058d --- /dev/null +++ b/doc/source/virtualenv.rst @@ -0,0 +1,203 @@ + +.. _silx-venv: + +Installing silx in a virtualenv +=============================== + +This step-by-step guide explains how to install *silx* in a virtualenv. + + +Prerequisites +------------- + +This guide assumes that your system meets the following requirements: + + - a version of python compatible with *silx* is installed (python 2.7 or python >= 3.5) + - the *pip* installer for python packages is installed + - the Qt and PyQt libraries are installed (optional, required for using ``silx.gui``) + +Installation procedure +---------------------- + + +Install vitrualenv +****************** + +.. code-block:: bash + + pip install virtualenv --user + +.. note:: + + This step is not required for recent version of Python 3. + Virtual environments are created using a builtin standard library, + ``venv``. + On Debian platforms, you might need to install the ``python3-venv`` + package. + + +Create a virtualenv +******************* + +The files required by a virtual environment are created in a new folder +with the same name as the virtualenv. So make sure you are in a directory +in which you have write permissions. + +In this tutorial we use a folder ``venvs`` in our home directory, and we create +a virtual environment named ``silx_venv`` + +.. code-block:: bash + + cd + mkdir -p venvs + cd venvs + virtualenv silx_venv + + +A virtualenv contains a copy of your default python interpreter with a few tools +to install packages (pip, setuptools). + +To use a different python interpreter, you can specify it on the command line. +For example, to use python 3.4: + +.. code-block:: bash + + virtualenv -p /usr/bin/python3.4 silx_venv + +But for python 3 you should use the builtin ``venv`` module: + +.. code-block:: bash + + python3 -m venv /path/to/new/virtual/environment + +.. note:: + + If you don't need to start with a clean environment and you don't want + to install each required library one by one, you can use a command line + option to create a virtualenv with access to all system packages: + ``--system-site-packages`` + + +Activate a virtualenv +********************* + +A script is provided in your virtualenv to activate it. + +.. code-block:: bash + + source silx_venv/bin/activate + +After activating your new virtualenv, this python interpreter and its +package tools are used, instead of the ones from the system. + +Any libraries you will install or upgrade will be inside the virtual +environment, and will not affect the rest of system. + +To deactivate the virtual environment, just type ``deactivate``. + +Upgrade pip +*********** + +After activating *silx_venv*, you should upgrade *pip*: + +.. code-block:: bash + + python -m pip install --upgrade pip + + +Upgrade setuptools and wheel +**************************** + +Upgrading the python packaging related libraries can make installing the +rest of the libraries much easier. + +.. code-block:: bash + + pip install setuptools --upgrade + pip install wheel --upgrade + +Install build dependencies +************************** + +The following command installs libraries that are required to build and +install *silx*: + +.. code-block:: bash + + pip install numpy cython + +.. since 0.5, numpy is now automatically installed when doing `pip install silx` + +Install optional dependencies +***************************** + +The following command installs libraries that are needed by various modules +of *silx*: + +.. code-block:: bash + + pip install matplotlib fabio h5py + +The next command installs libraries that are used by the python modules +handling parallel computing: + +.. code-block:: bash + + pip install pyopencl mako + + +Install pyqt +************ + +If your python version is 3.5 or newer, installing PyQt5 and all required packages +is as simple as typing: + +.. code-block:: bash + + pip install PyQt5 + +For previous versions of python, there are no PyQt wheels available, so the installation +is not as simple. + +The simplest way, assuming that PyQt is installed on your system, is to use that +system package directly. For this, you need to add a symbolic link to your virtualenv. + +If you want to use PyQt4 installed in ``/usr/lib/python2.7/dist-packages/``, type: + +.. code-block:: bash + + ln -s /usr/lib/python2.7/dist-packages/PyQt4 silx_venv/lib/python2.7/site-packages/ + ln -s /usr/lib/python2.7/dist-packages/sip.so silx_venv/lib/python2.7/site-packages/ + + +Install silx +************ + +.. code-block:: bash + + pip install silx + + +To test *silx*, open an interactive python console. If you managed to install PyQt or PySide +in your virtualenv, type: + +.. code-block:: bash + + python + +If you don't have PyQt, use: + +.. code-block:: bash + + WITH_QT_TEST=False python + +Run the test suite using: + + >>> import silx.test + >>> silx.test.run_tests() + + + + + + -- cgit v1.2.3